mirror of
git://projects.qi-hardware.com/nn-usb-fpga.git
synced 2025-04-21 12:27:27 +03:00
Adding lm32 demo to SAKC project
This commit is contained in:
43
lm32/logic/sakc/rtl/lac/dp_ram.v
Normal file
43
lm32/logic/sakc/rtl/lac/dp_ram.v
Normal file
@@ -0,0 +1,43 @@
|
||||
//------------------------------------------------------------------
|
||||
// Dual port memory (one read and one write port, same width)
|
||||
//------------------------------------------------------------------
|
||||
|
||||
module dp_ram #(
|
||||
parameter adr_width = 11,
|
||||
parameter dat_width = 8
|
||||
) (
|
||||
// read port a
|
||||
input clk_a,
|
||||
input [adr_width-1:0] adr_a,
|
||||
output reg [dat_width-1:0] dat_a,
|
||||
// write port b
|
||||
input clk_b,
|
||||
input [adr_width-1:0] adr_b,
|
||||
input [dat_width-1:0] dat_b,
|
||||
input we_b
|
||||
);
|
||||
|
||||
parameter depth = (1 << adr_width);
|
||||
|
||||
// actual ram cells
|
||||
reg [dat_width-1:0] ram [0:depth-1];
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// read port
|
||||
//------------------------------------------------------------------
|
||||
always @(posedge clk_a)
|
||||
begin
|
||||
dat_a <= ram[adr_a];
|
||||
end
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// write port
|
||||
//------------------------------------------------------------------
|
||||
always @(posedge clk_b)
|
||||
begin
|
||||
if (we_b) begin
|
||||
ram[adr_b] <= dat_b;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
262
lm32/logic/sakc/rtl/lac/lac.v
Normal file
262
lm32/logic/sakc/rtl/lac/lac.v
Normal file
@@ -0,0 +1,262 @@
|
||||
//------------------------------------------------------------------
|
||||
// Logic Analyzer Component
|
||||
//------------------------------------------------------------------
|
||||
|
||||
module lac #(
|
||||
parameter uart_freq_hz = 100000000,
|
||||
parameter uart_baud = 115200,
|
||||
parameter adr_width = 11,
|
||||
parameter width = 8
|
||||
) (
|
||||
input reset,
|
||||
input uart_clk,
|
||||
input uart_rxd,
|
||||
output uart_cts,
|
||||
output uart_txd,
|
||||
input uart_rts,
|
||||
// actual probe input
|
||||
input probe_clk,
|
||||
input [width-1:0] probe,
|
||||
output reg [7:0] select
|
||||
);
|
||||
|
||||
parameter cmd_nop = 8'h20;
|
||||
parameter cmd_arm = 8'h01;
|
||||
parameter cmd_disarm = 8'h02;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// uart instantiation
|
||||
//------------------------------------------------------------------
|
||||
assign uart_cts = 1;
|
||||
|
||||
reg tx_wr;
|
||||
wire tx_busy;
|
||||
reg [7:0] tx_data;
|
||||
|
||||
wire [7:0] rx_data;
|
||||
wire rx_avail;
|
||||
reg rx_ack;
|
||||
|
||||
uart #(
|
||||
.freq_hz( uart_freq_hz ),
|
||||
.baud( uart_baud )
|
||||
) uart0 (
|
||||
.reset( reset ),
|
||||
.clk( uart_clk ),
|
||||
// UART
|
||||
.uart_txd( uart_txd ),
|
||||
.uart_rxd( uart_rxd ),
|
||||
//
|
||||
.rx_data( rx_data ),
|
||||
.rx_avail( rx_avail ),
|
||||
.rx_error( rx_error ),
|
||||
.rx_ack( rx_ack ),
|
||||
.tx_data( tx_data ),
|
||||
.tx_wr( tx_wr ),
|
||||
.tx_busy( tx_busy )
|
||||
);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// handshake signal between clock domains
|
||||
//------------------------------------------------------------------
|
||||
reg [7:0] trig_mask;
|
||||
reg [7:0] trig_cond;
|
||||
reg [7:0] trig_pre;
|
||||
|
||||
reg [adr_width-1:0] start_adr; // set in probe_clk domain
|
||||
|
||||
reg armed; // set in uart_clk domain
|
||||
reg triggered; // set in probe_clk domain
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// uart state machine
|
||||
//------------------------------------------------------------------
|
||||
wire rx_req;
|
||||
assign rx_req = rx_avail & ~rx_ack;
|
||||
|
||||
reg triggered_synced;
|
||||
wire [width-1:0] read_dat;
|
||||
reg [adr_width-1:0] read_adr;
|
||||
wire [adr_width-1:0] read_adr_next;
|
||||
|
||||
assign read_adr_next = read_adr + 1;
|
||||
|
||||
reg [2:0] state;
|
||||
|
||||
parameter s_idle = 0;
|
||||
parameter s_read_select= 1;
|
||||
parameter s_read_mask = 2;
|
||||
parameter s_read_comp = 3;
|
||||
parameter s_read_pre = 4;
|
||||
parameter s_triggered = 5;
|
||||
parameter s_send_byte = 6;
|
||||
|
||||
always @(posedge uart_clk)
|
||||
begin
|
||||
if (reset) begin
|
||||
state <= s_idle;
|
||||
select <= 0;
|
||||
armed <= 0;
|
||||
tx_wr <= 0;
|
||||
end else begin
|
||||
triggered_synced <= triggered;
|
||||
|
||||
rx_ack <= 0; // default until set otherwise
|
||||
tx_wr <= 0;
|
||||
|
||||
case (state)
|
||||
s_idle: begin
|
||||
|
||||
if (rx_req) begin
|
||||
case (rx_data)
|
||||
cmd_arm: begin
|
||||
rx_ack <= 1;
|
||||
state <= s_read_select;
|
||||
end
|
||||
cmd_disarm: begin
|
||||
rx_ack <= 1;
|
||||
armed <= 0;
|
||||
end
|
||||
default: begin
|
||||
rx_ack <= 1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
if (~rx_req && triggered_synced) begin
|
||||
state <= s_triggered;
|
||||
end
|
||||
end
|
||||
s_read_select: begin
|
||||
if (rx_req) begin
|
||||
rx_ack <= 1;
|
||||
select <= rx_data;
|
||||
state <= s_read_mask;
|
||||
end
|
||||
end
|
||||
s_read_mask: begin
|
||||
if (rx_req) begin
|
||||
rx_ack <= 1;
|
||||
trig_mask <= rx_data;
|
||||
state <= s_read_comp;
|
||||
end
|
||||
end
|
||||
s_read_comp: begin
|
||||
if (rx_req) begin
|
||||
rx_ack <= 1;
|
||||
trig_cond <= rx_data;
|
||||
armed <= 1;
|
||||
state <= s_read_pre;
|
||||
end
|
||||
end
|
||||
s_read_pre: begin
|
||||
if (rx_req) begin
|
||||
rx_ack <= 1;
|
||||
trig_pre <= rx_data;
|
||||
armed <= 1;
|
||||
state <= s_idle;
|
||||
end
|
||||
end
|
||||
s_triggered: begin
|
||||
armed <= 0;
|
||||
read_adr <= start_adr;
|
||||
tx_data <= adr_width;
|
||||
tx_wr <= 1;
|
||||
state <= s_send_byte;
|
||||
end
|
||||
s_send_byte: begin
|
||||
tx_wr <= 0;
|
||||
|
||||
if (~tx_busy & ~tx_wr) begin
|
||||
if (read_adr_next == start_adr)
|
||||
state <= s_idle;
|
||||
|
||||
read_adr <= read_adr_next;
|
||||
tx_data <= read_dat;
|
||||
tx_wr <= 1;
|
||||
end
|
||||
end
|
||||
default:
|
||||
state <= s_idle;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Sampling clock domain
|
||||
//------------------------------------------------------------------
|
||||
|
||||
// register probe input for better F_max
|
||||
reg [width-1:0] probe_r;
|
||||
|
||||
always @(posedge probe_clk)
|
||||
probe_r <= probe;
|
||||
|
||||
// Sampling machinery
|
||||
reg armed_synced;
|
||||
reg armed_synced2;
|
||||
reg sampling;
|
||||
|
||||
reg [adr_width-1:0] write_adr;
|
||||
wire [adr_width-1:0] next_adr;
|
||||
assign next_adr = write_adr + 1;
|
||||
|
||||
wire cond_match;
|
||||
assign cond_match = (probe_r & trig_mask) == (trig_cond & trig_mask) && armed_synced2;
|
||||
|
||||
always @(posedge probe_clk)
|
||||
begin
|
||||
if (reset) begin
|
||||
armed_synced <= 0;
|
||||
armed_synced2 <= 0;
|
||||
sampling <= 0;
|
||||
triggered <= 0;
|
||||
write_adr <= 0;
|
||||
end else begin
|
||||
armed_synced <= armed;
|
||||
armed_synced2 <= armed_synced;
|
||||
|
||||
if (armed_synced2 || sampling) begin
|
||||
write_adr <= next_adr;
|
||||
end
|
||||
|
||||
if (~triggered && armed_synced2) begin
|
||||
if (cond_match) begin
|
||||
sampling <= 1;
|
||||
triggered <= 1;
|
||||
start_adr <= write_adr;
|
||||
end
|
||||
end
|
||||
|
||||
if (sampling && next_adr == start_adr) begin
|
||||
sampling <= 0;
|
||||
end
|
||||
|
||||
if (~sampling && ~armed_synced2 && triggered)
|
||||
triggered <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// dual port memory
|
||||
//------------------------------------------------------------------
|
||||
wire write_en;
|
||||
assign write_en = sampling || cond_match;
|
||||
|
||||
dp_ram #(
|
||||
.adr_width( adr_width ),
|
||||
.dat_width( width )
|
||||
) ram0 (
|
||||
// read port a
|
||||
.clk_a( uart_clk ),
|
||||
.adr_a( read_adr ),
|
||||
.dat_a( read_dat ),
|
||||
// write port b
|
||||
.clk_b( probe_clk ),
|
||||
.adr_b( write_adr ),
|
||||
.dat_b( probe_r ),
|
||||
.we_b( write_en )
|
||||
);
|
||||
|
||||
endmodule
|
||||
155
lm32/logic/sakc/rtl/lac/uart.v
Normal file
155
lm32/logic/sakc/rtl/lac/uart.v
Normal file
@@ -0,0 +1,155 @@
|
||||
//-----------------------------------------------------
|
||||
// Design Name : uart
|
||||
// File Name : uart.v
|
||||
//-----------------------------------------------------
|
||||
module uart #(
|
||||
parameter freq_hz = 100000000,
|
||||
parameter baud = 115200
|
||||
) (
|
||||
input reset,
|
||||
input clk,
|
||||
// UART lines
|
||||
input uart_rxd,
|
||||
output reg uart_txd,
|
||||
//
|
||||
output reg [7:0] rx_data,
|
||||
output reg rx_avail,
|
||||
output reg rx_error,
|
||||
input rx_ack,
|
||||
input [7:0] tx_data,
|
||||
input tx_wr,
|
||||
output reg tx_busy
|
||||
);
|
||||
|
||||
parameter divisor = freq_hz/baud/16;
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// enable16 generator
|
||||
//-----------------------------------------------------------------
|
||||
reg [15:0] enable16_counter;
|
||||
|
||||
wire enable16;
|
||||
assign enable16 = (enable16_counter == 0);
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (reset) begin
|
||||
enable16_counter <= divisor-1;
|
||||
end else begin
|
||||
enable16_counter <= enable16_counter - 1;
|
||||
if (enable16_counter == 0) begin
|
||||
enable16_counter <= divisor-1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// syncronize uart_rxd
|
||||
//-----------------------------------------------------------------
|
||||
reg uart_rxd1;
|
||||
reg uart_rxd2;
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
uart_rxd1 <= uart_rxd;
|
||||
uart_rxd2 <= uart_rxd1;
|
||||
end
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// UART RX Logic
|
||||
//-----------------------------------------------------------------
|
||||
reg rx_busy;
|
||||
reg [3:0] rx_count16;
|
||||
reg [3:0] rx_bitcount;
|
||||
reg [7:0] rxd_reg;
|
||||
|
||||
always @ (posedge clk)
|
||||
begin
|
||||
if (reset) begin
|
||||
rx_busy <= 0;
|
||||
rx_count16 <= 0;
|
||||
rx_bitcount <= 0;
|
||||
rx_avail <= 0;
|
||||
rx_error <= 0;
|
||||
end else begin
|
||||
if (rx_ack) begin
|
||||
rx_avail <= 0;
|
||||
rx_error <= 0;
|
||||
end
|
||||
|
||||
if (enable16) begin
|
||||
if (!rx_busy) begin // look for start bit
|
||||
if (!uart_rxd2) begin // start bit found
|
||||
rx_busy <= 1;
|
||||
rx_count16 <= 7;
|
||||
rx_bitcount <= 0;
|
||||
end
|
||||
end else begin
|
||||
rx_count16 <= rx_count16 + 1;
|
||||
|
||||
if (rx_count16 == 0) begin // sample
|
||||
rx_bitcount <= rx_bitcount + 1;
|
||||
|
||||
if (rx_bitcount == 0) begin // verify startbit
|
||||
if (uart_rxd2) begin
|
||||
rx_busy <= 0;
|
||||
end
|
||||
end else if (rx_bitcount == 9) begin // look for stop bit
|
||||
rx_busy <= 0;
|
||||
if (uart_rxd2) begin // stop bit ok
|
||||
rx_data <= rxd_reg;
|
||||
rx_avail <= 1;
|
||||
rx_error <= 0;
|
||||
end else begin // bas stop bit
|
||||
rx_error <= 1;
|
||||
end
|
||||
end else begin
|
||||
rxd_reg <= { uart_rxd2, rxd_reg[7:1] };
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// UART TX Logic
|
||||
//-----------------------------------------------------------------
|
||||
reg [3:0] tx_bitcount;
|
||||
reg [3:0] tx_count16;
|
||||
reg [7:0] txd_reg;
|
||||
|
||||
always @ (posedge clk)
|
||||
begin
|
||||
if (reset) begin
|
||||
tx_busy <= 0;
|
||||
uart_txd <= 1;
|
||||
end else begin
|
||||
if (tx_wr && !tx_busy) begin
|
||||
txd_reg <= tx_data;
|
||||
tx_bitcount <= 0;
|
||||
tx_count16 <= 1;
|
||||
tx_busy <= 1;
|
||||
uart_txd <= 0;
|
||||
end else if (enable16 && tx_busy) begin
|
||||
tx_count16 <= tx_count16 + 1;
|
||||
|
||||
if (tx_count16 == 0) begin
|
||||
tx_bitcount <= tx_bitcount + 1;
|
||||
|
||||
if (tx_bitcount == 8) begin
|
||||
uart_txd <= 'b1;
|
||||
end else if (tx_bitcount == 9) begin
|
||||
uart_txd <= 'b1;
|
||||
tx_busy <= 0;
|
||||
end else begin
|
||||
uart_txd <= txd_reg[0];
|
||||
txd_reg <= { 1'b0, txd_reg[7:1] };
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user