diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d470629 --- /dev/null +++ b/Makefile @@ -0,0 +1,48 @@ +build: + python3 -m build + +pypi_upload: build + python3 -m twine upload --repository testpypi dist/* + + + +sim: sim_bit_fifo sim_bridge_rx sim_bridge_tx fifo_tb lut_mem_tb uart_tx_tb + +sim_bit_fifo: + iverilog -g2012 -o sim.out test/bit_fifo_tb.sv src/manta/bit_fifo.v + vvp sim.out + rm sim.out + +sim_bridge_rx: + iverilog -g2012 -o sim.out test/bridge_rx_tb.sv src/manta/bridge_rx.v + vvp sim.out + rm sim.out + +sim_bridge_tx: + iverilog -g2012 -o sim.out test/bridge_tx_tb.sv src/manta/bridge_tx.v src/manta/uart_tx.v + vvp sim.out + rm sim.out + +fifo_tb: + iverilog -g2012 -o sim.out test/fifo_tb.sv src/manta/fifo.v src/manta/xilinx_true_dual_port_read_first_2_clock_ram.v + vvp sim.out >> /dev/null # this one is noisy right now + rm sim.out + +lut_mem_tb: + iverilog -g2012 -o sim.out test/lut_mem_tb.sv src/manta/lut_mem.v + vvp sim.out + rm sim.out + +uart_tb: + iverilog -g2012 -o sim.out test/uart_tb.sv src/manta/tx_uart.v src/manta/uart_rx.v + vvp sim.out + rm sim.out + +uart_tx_tb: + iverilog -g2012 -o sim.out test/uart_tx_tb.sv src/manta/tx_uart.v src/manta/uart_tx.v src/manta/rx_uart.v + vvp sim.out + rm sim.out + +clean: + rm *.out *.vcd + rm -rf dist/ diff --git a/src/manta/bridge_rx.v b/src/manta/bridge_rx.v index 4e6c8f8..a462f3b 100644 --- a/src/manta/bridge_rx.v +++ b/src/manta/bridge_rx.v @@ -4,16 +4,20 @@ module bridge_rx( input wire clk, - input wire[7:0] axiid, - input wire axiiv, + input wire[7:0] rx_data, + input wire rx_valid, - output reg[15:0] req_addr, - output reg[15:0] req_data, - output reg req_rw, - output reg req_valid, - input wire req_ready + output reg[15:0] addr_o, + output reg[15:0] wdata_o, + output reg rw_o, + output reg valid_o ); + +// this is a hack, the FSM needs to be updated +// but this will bypass it for now +parameter ready_i = 1; + parameter ADDR_WIDTH = 0; parameter DATA_WIDTH = 0; @@ -30,40 +34,40 @@ reg [3:0] bytes_received; // no global resets! initial begin - req_addr = 0; - req_data = 0; - req_rw = 0; - req_valid = 0; + addr_o = 0; + wdata_o = 0; + rw_o = 0; + valid_o = 0; bytes_received = 0; state = ACQUIRE; end -reg [3:0] axiid_decoded; -reg axiid_is_0_thru_9; -reg axiid_is_A_thru_F; +reg [3:0] rx_data_decoded; +reg rx_data_is_0_thru_9; +reg rx_data_is_A_thru_F; always @(*) begin - axiid_is_0_thru_9 = (axiid >= 8'h30) & (axiid <= 8'h39); - axiid_is_A_thru_F = (axiid >= 8'h41) & (axiid <= 8'h46); + rx_data_is_0_thru_9 = (rx_data >= 8'h30) & (rx_data <= 8'h39); + rx_data_is_A_thru_F = (rx_data >= 8'h41) & (rx_data <= 8'h46); - if (axiid_is_0_thru_9) axiid_decoded = axiid - 8'h30; - else if (axiid_is_A_thru_F) axiid_decoded = axiid - 8'h41 + 'd10; - else axiid_decoded = 0; + if (rx_data_is_0_thru_9) rx_data_decoded = rx_data - 8'h30; + else if (rx_data_is_A_thru_F) rx_data_decoded = rx_data - 8'h41 + 'd10; + else rx_data_decoded = 0; end always @(posedge clk) begin if (state == ACQUIRE) begin - if(axiiv) begin + if(rx_valid) begin if (bytes_received == 0) begin - if(axiid == PREAMBLE) bytes_received <= 1; + if(rx_data == PREAMBLE) bytes_received <= 1; end else if( (bytes_received >= 1) & (bytes_received <= 4) ) begin // only advance if byte is valid hex digit - if(axiid_is_0_thru_9 | axiid_is_A_thru_F) begin - req_addr <= (req_addr << 4) | axiid_decoded; + if(rx_data_is_0_thru_9 | rx_data_is_A_thru_F) begin + addr_o <= (addr_o << 4) | rx_data_decoded; bytes_received <= bytes_received + 1; end @@ -71,16 +75,16 @@ always @(posedge clk) begin end else if( bytes_received == 5) begin - if( (axiid == CR) | (axiid == LF)) begin - req_valid <= 1; - req_rw = 0; + if( (rx_data == CR) | (rx_data == LF)) begin + valid_o <= 1; + rw_o = 0; bytes_received <= 0; state <= TRANSMIT; end - else if (axiid_is_0_thru_9 | axiid_is_A_thru_F) begin + else if (rx_data_is_0_thru_9 | rx_data_is_A_thru_F) begin bytes_received <= bytes_received + 1; - req_data <= (req_data << 4) | axiid_decoded; + wdata_o <= (wdata_o << 4) | rx_data_decoded; end else state <= ERROR; @@ -88,8 +92,8 @@ always @(posedge clk) begin else if ( (bytes_received >= 6) & (bytes_received <= 8) ) begin - if (axiid_is_0_thru_9 | axiid_is_A_thru_F) begin - req_data <= (req_data << 4) | axiid_decoded; + if (rx_data_is_0_thru_9 | rx_data_is_A_thru_F) begin + wdata_o <= (wdata_o << 4) | rx_data_decoded; bytes_received <= bytes_received + 1; end @@ -98,9 +102,9 @@ always @(posedge clk) begin else if (bytes_received == 9) begin bytes_received <= 0; - if( (axiid == CR) | (axiid == LF)) begin - req_valid <= 1; - req_rw <= 1; + if( (rx_data == CR) | (rx_data == LF)) begin + valid_o <= 1; + rw_o <= 1; state <= TRANSMIT; end @@ -111,14 +115,14 @@ always @(posedge clk) begin else if (state == TRANSMIT) begin - if(req_ready) begin - req_valid <= 0; + if(ready_i) begin + valid_o <= 0; state <= ACQUIRE; end - if(axiiv) begin - if ( (axiid != CR) & (axiid != LF)) begin - req_valid <= 0; + if(rx_valid) begin + if ( (rx_data != CR) & (rx_data != LF)) begin + valid_o <= 0; state <= ERROR; end end diff --git a/src/manta/bridge_tx.v b/src/manta/bridge_tx.v index 7376739..b6ed4c0 100644 --- a/src/manta/bridge_tx.v +++ b/src/manta/bridge_tx.v @@ -7,9 +7,9 @@ module bridge_tx( input wire [15:0] rdata_i, input wire rw_i, input wire valid_i, - input wire ready_i, output reg [7:0] data_o, + input wire ready_i, output reg valid_o); localparam PREAMBLE = 8'h4D; diff --git a/src/manta/fifo.v b/src/manta/fifo.v new file mode 100644 index 0000000..6a90a67 --- /dev/null +++ b/src/manta/fifo.v @@ -0,0 +1,84 @@ +`default_nettype none +`timescale 1ns / 1ps + +module fifo ( + input wire clk, + input wire rst, + + input wire [WIDTH - 1:0] data_in, + input wire input_ready, + + input wire request_output, + output reg [WIDTH - 1:0] data_out, + output reg output_valid, + + output reg [AW:0] size, + output reg empty, + output reg full + ); + + parameter WIDTH = 8; + parameter DEPTH = 4096; + localparam AW = $clog2(DEPTH); + + reg [AW:0] write_pointer; + reg [AW:0] read_pointer; + + reg empty_int; + assign empty_int = (write_pointer[AW] == read_pointer[AW]); + + reg full_or_empty; + assign full_or_empty = (write_pointer[AW-1:0] == read_pointer[AW-1:0]); + + assign full = full_or_empty & !empty_int; + assign empty = full_or_empty & empty_int; + assign size = write_pointer - read_pointer; + + reg output_valid_pip_0; + reg output_valid_pip_1; + + always @(posedge clk) begin + if (input_ready && ~full) + write_pointer <= write_pointer + 1'd1; + + if (request_output && ~empty) + read_pointer <= read_pointer + 1'd1; + output_valid_pip_0 <= request_output; + output_valid_pip_1 <= output_valid_pip_0; + output_valid <= output_valid_pip_1; + + if (rst) begin + read_pointer <= 0; + write_pointer <= 0; + end + end + + xilinx_true_dual_port_read_first_2_clock_ram #( + .RAM_WIDTH(WIDTH), + .RAM_DEPTH(DEPTH), + .RAM_PERFORMANCE("HIGH_PERFORMANCE") + + ) buffer ( + + // write port + .clka(clk), + .rsta(rst), + .ena(1), + .addra(write_pointer), + .dina(data_in), + .wea(input_ready), + .regcea(1), + .douta(), + + // read port + .clkb(clk), + .rstb(rst), + .enb(1), + .addrb(read_pointer), + .dinb(), + .web(0), + .regceb(1), + .doutb(data_out)); + endmodule + +`default_nettype wire diff --git a/src/manta/lut_mem.v b/src/manta/lut_mem.v index c0e596a..d95f49f 100644 --- a/src/manta/lut_mem.v +++ b/src/manta/lut_mem.v @@ -21,6 +21,7 @@ module lut_mem( parameter DEPTH = 8; parameter BASE_ADDR = 0; +parameter READ_ONLY = 0; reg [DEPTH-1:0][15:0] mem; always @(posedge clk) begin @@ -37,7 +38,7 @@ always @(posedge clk) begin if( (addr_i >= BASE_ADDR) && (addr_i <= BASE_ADDR + DEPTH - 1) ) begin // read/write - if (rw_i) mem[addr_i - BASE_ADDR] <= wdata_i; + if (rw_i && !READ_ONLY) mem[addr_i - BASE_ADDR] <= wdata_i; else rdata_o <= mem[addr_i - BASE_ADDR]; end end diff --git a/src/manta/xilinx_true_dual_port_read_first_2_clock_ram.v b/src/manta/xilinx_true_dual_port_read_first_2_clock_ram.v new file mode 100644 index 0000000..7e975e5 --- /dev/null +++ b/src/manta/xilinx_true_dual_port_read_first_2_clock_ram.v @@ -0,0 +1,149 @@ + +// Xilinx True Dual Port RAM, Read First, Dual Clock +// This code implements a parameterizable true dual port memory (both ports can read and write). +// The behavior of this RAM is when data is written, the prior memory contents at the write +// address are presented on the output port. If the output data is +// not needed during writes or the last read value is desired to be retained, +// it is suggested to use a no change RAM as it is more power efficient. +// If a reset or enable is not necessary, it may be tied off or removed from the code. + +module xilinx_true_dual_port_read_first_2_clock_ram #( + parameter RAM_WIDTH = 18, // Specify RAM data width + parameter RAM_DEPTH = 1024, // Specify RAM depth (number of entries) + parameter RAM_PERFORMANCE = "HIGH_PERFORMANCE", // Select "HIGH_PERFORMANCE" or "LOW_LATENCY" + parameter INIT_FILE = "" // Specify name/location of RAM initialization file if using one (leave blank if not) +) ( + input [clogb2(RAM_DEPTH-1)-1:0] addra, // Port A address bus, width determined from RAM_DEPTH + input [clogb2(RAM_DEPTH-1)-1:0] addrb, // Port B address bus, width determined from RAM_DEPTH + input [RAM_WIDTH-1:0] dina, // Port A RAM input data + input [RAM_WIDTH-1:0] dinb, // Port B RAM input data + input clka, // Port A clock + input clkb, // Port B clock + input wea, // Port A write enable + input web, // Port B write enable + input ena, // Port A RAM Enable, for additional power savings, disable port when not in use + input enb, // Port B RAM Enable, for additional power savings, disable port when not in use + input rsta, // Port A output reset (does not affect memory contents) + input rstb, // Port B output reset (does not affect memory contents) + input regcea, // Port A output register enable + input regceb, // Port B output register enable + output [RAM_WIDTH-1:0] douta, // Port A RAM output data + output [RAM_WIDTH-1:0] doutb // Port B RAM output data +); + + reg [RAM_WIDTH-1:0] BRAM [RAM_DEPTH-1:0]; + reg [RAM_WIDTH-1:0] ram_data_a = {RAM_WIDTH{1'b0}}; + reg [RAM_WIDTH-1:0] ram_data_b = {RAM_WIDTH{1'b0}}; + + //this loop below allows for rendering with iverilog simulations! + /* + integer idx; + for(idx = 0; idx < RAM_DEPTH; idx = idx+1) begin: cats + wire [RAM_WIDTH-1:0] tmp; + assign tmp = BRAM[idx]; + end + */ + + // The following code either initializes the memory values to a specified file or to all zeros to match hardware + generate + if (INIT_FILE != "") begin: use_init_file + initial + $readmemh(INIT_FILE, BRAM, 0, RAM_DEPTH-1); + end else begin: init_bram_to_zero + integer ram_index; + initial + for (ram_index = 0; ram_index < RAM_DEPTH; ram_index = ram_index + 1) + BRAM[ram_index] = {RAM_WIDTH{1'b0}}; + end + endgenerate + integer idx; + // initial begin + // for (idx = 0; idx < RAM_DEPTH; idx = idx + 1) begin + // $dumpvars(0, BRAM[idx]); + // end + // end + always @(posedge clka) + if (ena) begin + if (wea) + BRAM[addra] <= dina; + ram_data_a <= BRAM[addra]; + end + + always @(posedge clkb) + if (enb) begin + if (web) + BRAM[addrb] <= dinb; + ram_data_b <= BRAM[addrb]; + end + + // The following code generates HIGH_PERFORMANCE (use output register) or LOW_LATENCY (no output register) + generate + if (RAM_PERFORMANCE == "LOW_LATENCY") begin: no_output_register + + // The following is a 1 clock cycle read latency at the cost of a longer clock-to-out timing + assign douta = ram_data_a; + assign doutb = ram_data_b; + + end else begin: output_register + + // The following is a 2 clock cycle read latency with improve clock-to-out timing + + reg [RAM_WIDTH-1:0] douta_reg = {RAM_WIDTH{1'b0}}; + reg [RAM_WIDTH-1:0] doutb_reg = {RAM_WIDTH{1'b0}}; + + always @(posedge clka) + if (rsta) + douta_reg <= {RAM_WIDTH{1'b0}}; + else if (regcea) + douta_reg <= ram_data_a; + + always @(posedge clkb) + if (rstb) + doutb_reg <= {RAM_WIDTH{1'b0}}; + else if (regceb) + doutb_reg <= ram_data_b; + + assign douta = douta_reg; + assign doutb = doutb_reg; + + end + endgenerate + + // The following function calculates the address width based on specified RAM depth + function integer clogb2; + input integer depth; + for (clogb2=0; depth>0; clogb2=clogb2+1) + depth = depth >> 1; + endfunction + +endmodule + +// The following is an instantiation template for xilinx_true_dual_port_read_first_2_clock_ram +/* + // Xilinx True Dual Port RAM, Read First, Dual Clock + xilinx_true_dual_port_read_first_2_clock_ram #( + .RAM_WIDTH(18), // Specify RAM data width + .RAM_DEPTH(1024), // Specify RAM depth (number of entries) + .RAM_PERFORMANCE("HIGH_PERFORMANCE"), // Select "HIGH_PERFORMANCE" or "LOW_LATENCY" + .INIT_FILE("") // Specify name/location of RAM initialization file if using one (leave blank if not) + ) your_instance_name ( + .addra(addra), // Port A address bus, width determined from RAM_DEPTH + .addrb(addrb), // Port B address bus, width determined from RAM_DEPTH + .dina(dina), // Port A RAM input data, width determined from RAM_WIDTH + .dinb(dinb), // Port B RAM input data, width determined from RAM_WIDTH + .clka(clka), // Port A clock + .clkb(clkb), // Port B clock + .wea(wea), // Port A write enable + .web(web), // Port B write enable + .ena(ena), // Port A RAM Enable, for additional power savings, disable port when not in use + .enb(enb), // Port B RAM Enable, for additional power savings, disable port when not in use + .rsta(rsta), // Port A output reset (does not affect memory contents) + .rstb(rstb), // Port B output reset (does not affect memory contents) + .regcea(regcea), // Port A output register enable + .regceb(regceb), // Port B output register enable + .douta(douta), // Port A RAM output data, width determined from RAM_WIDTH + .doutb(doutb) // Port B RAM output data, width determined from RAM_WIDTH + ); +*/ + + diff --git a/test/bridge_rx_tb.sv b/test/bridge_rx_tb.sv index bfed07d..b90d9b6 100644 --- a/test/bridge_rx_tb.sv +++ b/test/bridge_rx_tb.sv @@ -5,12 +5,12 @@ `define HCP 5 `define SEND_MESSAGE(MESSAGE) \ - uart_rx_axiov = 1; \ + rx_valid = 1; \ for(int i=0; i < $size(MESSAGE); i++) begin \ - uart_rx_axiod = MESSAGE[i]; \ + rx_data = MESSAGE[i]; \ #`CP; \ end \ - uart_rx_axiov = 0; \ + rx_valid = 0; \ module bridge_rx_tb; // https://www.youtube.com/watch?v=WCOAr-96bGc @@ -22,34 +22,32 @@ string message; integer test_num; // uart inputs and outputs -logic rxd; -logic [7:0] uart_rx_axiod; -logic uart_rx_axiov; +logic rx; +logic [7:0] rx_data; +logic rx_valid; // the parameter will all get filled out in manta's big instantiator thing hehehee parameter ADDR_WIDTH = 16; // $clog2( how much memory we need rounded up to the nearest 8 ) parameter DATA_WIDTH = 16; // request bus, gets connected to uart_rx (through a FSM) -logic [ADDR_WIDTH-1:0] req_addr; -logic [DATA_WIDTH-1:0] req_data; -logic req_rw; -logic req_valid; +logic [ADDR_WIDTH-1:0] addr; +logic [DATA_WIDTH-1:0] wdata; +logic rw; +logic valid; logic req_ready; bridge_rx bridge_rx_uut( .clk(clk), - .rst(rst), // connect to uart_rx - .axiid(uart_rx_axiod), - .axiiv(uart_rx_axiov), + .rx_data(rx_data), + .rx_valid(rx_valid), - .req_addr(req_addr), - .req_data(req_data), - .req_rw(req_rw), - .req_valid(req_valid), - .req_ready(req_ready)); + .addr_o(addr), + .wdata_o(wdata), + .rw_o(rw), + .valid_o(valid)); always begin #`HCP @@ -63,8 +61,8 @@ initial begin // setup and reset clk = 0; rst = 0; - uart_rx_axiod = 0; - uart_rx_axiov = 0; + rx_data = 0; + rx_valid = 0; req_ready = 1; test_num = 0; #`CP @@ -78,9 +76,9 @@ initial begin message = {"M12345678", 8'h0D, 8'h0A}; `SEND_MESSAGE(message) - assert(req_addr == 16'h1234) else $error("incorrect addr!"); - assert(req_data == 16'h5678) else $error("incorrect data!"); - assert(req_rw == 1) else $error("incorrect rw!"); + assert(addr == 16'h1234) else $error("incorrect addr!"); + assert(wdata == 16'h5678) else $error("incorrect data!"); + assert(rw == 1) else $error("incorrect rw!"); assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state after transmission"); #(10*`CP); @@ -94,9 +92,9 @@ initial begin message = {"MDEADBEEF", 8'h0D, 8'h0A}; `SEND_MESSAGE(message) - assert(req_addr == 16'hDEAD) else $error("incorrect addr!"); - assert(req_data == 16'hBEEF) else $error("incorrect data!"); - assert(req_rw == 1) else $error("incorrect rw!"); + assert(addr == 16'hDEAD) else $error("incorrect addr!"); + assert(wdata == 16'hBEEF) else $error("incorrect data!"); + assert(rw == 1) else $error("incorrect rw!"); assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state after transmission"); #(10*`CP); @@ -110,8 +108,8 @@ initial begin message = {"MBABE", 8'h0D, 8'h0A}; `SEND_MESSAGE(message) - assert(req_addr == 16'hBABE) else $error("incorrect addr!"); - assert(req_rw == 0) else $error("incorrect rw!"); + assert(addr == 16'hBABE) else $error("incorrect addr!"); + assert(rw == 0) else $error("incorrect rw!"); assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state after transmission"); #(10*`CP); @@ -124,8 +122,8 @@ initial begin message = {"M0000", 8'h0D}; `SEND_MESSAGE(message) - assert(req_addr == 16'h0000) else $error("incorrect addr!"); - assert(req_rw == 0) else $error("incorrect rw!"); + assert(addr == 16'h0000) else $error("incorrect addr!"); + assert(rw == 0) else $error("incorrect rw!"); assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state after transmission"); #(10*`CP); @@ -138,8 +136,8 @@ initial begin message = {"M1234", 8'h0D}; `SEND_MESSAGE(message) - assert(req_addr == 16'h1234) else $error("incorrect addr!"); - assert(req_rw == 0) else $error("incorrect rw!"); + assert(addr == 16'h1234) else $error("incorrect addr!"); + assert(rw == 0) else $error("incorrect rw!"); assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state after transmission"); #(10*`CP); @@ -152,9 +150,9 @@ initial begin message = {"MF00DBEEF", 8'h0D}; `SEND_MESSAGE(message) - assert(req_addr == 16'hF00D) else $error("incorrect addr!"); - assert(req_data == 16'hBEEF) else $error("incorrect data!"); - assert(req_rw == 1) else $error("incorrect rw!"); + assert(addr == 16'hF00D) else $error("incorrect addr!"); + assert(wdata == 16'hBEEF) else $error("incorrect data!"); + assert(rw == 1) else $error("incorrect rw!"); assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state after transmission"); #(10*`CP); @@ -167,9 +165,9 @@ initial begin message = {"MB0BACAFE", 8'h0D}; `SEND_MESSAGE(message) - assert(req_addr == 16'hB0BA) else $error("incorrect addr!"); - assert(req_data == 16'hCAFE) else $error("incorrect data!"); - assert(req_rw == 1) else $error("incorrect rw!"); + assert(addr == 16'hB0BA) else $error("incorrect addr!"); + assert(wdata == 16'hCAFE) else $error("incorrect data!"); + assert(rw == 1) else $error("incorrect rw!"); assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state after transmission"); #(10*`CP); @@ -183,7 +181,7 @@ initial begin message = {"MABC", 8'h0D, 8'h0A}; `SEND_MESSAGE(message) - assert(req_valid == 0) else $error("valid asserted for bad message"); + assert(valid == 0) else $error("valid asserted for bad message"); assert(bridge_rx_uut.state == bridge_rx_uut.ERROR) else $error("not in error state after transmission"); #(10*`CP); @@ -198,7 +196,7 @@ initial begin message = {"MABC", 8'h0D, 8'h0A}; `SEND_MESSAGE(message) - assert(req_valid == 0) else $error("valid asserted for bad message"); + assert(valid == 0) else $error("valid asserted for bad message"); assert(bridge_rx_uut.state == bridge_rx_uut.ERROR) else $error("not in error state after transmission"); #(10*`CP); @@ -213,7 +211,7 @@ initial begin message = {"MABC", 8'h0D, 8'h0A}; `SEND_MESSAGE(message) - assert(req_valid == 0) else $error("valid asserted for bad message"); + assert(valid == 0) else $error("valid asserted for bad message"); assert(bridge_rx_uut.state == bridge_rx_uut.ERROR) else $error("not in error state after transmission"); #(10*`CP); @@ -228,7 +226,7 @@ initial begin message = {"MABC", 8'h0D, 8'h0A}; `SEND_MESSAGE(message) - assert(req_valid == 0) else $error("valid asserted for bad message"); + assert(valid == 0) else $error("valid asserted for bad message"); assert(bridge_rx_uut.state == bridge_rx_uut.ERROR) else $error("not in error state after transmission"); #(10*`CP); @@ -243,7 +241,7 @@ initial begin message = {"MABCG", 8'h0D, 8'h0A}; `SEND_MESSAGE(message) - assert(req_valid == 0) else $error("valid asserted for bad message"); + assert(valid == 0) else $error("valid asserted for bad message"); assert(bridge_rx_uut.state == bridge_rx_uut.ERROR) else $error("not in error state after transmission"); #(10*`CP); @@ -258,7 +256,7 @@ initial begin message = {"MABC[]()##*@", 8'h0D, 8'h0A}; `SEND_MESSAGE(message) - assert(req_valid == 0) else $error("valid asserted for bad message"); + assert(valid == 0) else $error("valid asserted for bad message"); assert(bridge_rx_uut.state == bridge_rx_uut.ERROR) else $error("not in error state after transmission"); #(10*`CP); @@ -273,7 +271,7 @@ initial begin message = {"M", 8'h0D, 8'h0A}; `SEND_MESSAGE(message) - assert(req_valid == 0) else $error("valid asserted for bad message"); + assert(valid == 0) else $error("valid asserted for bad message"); assert(bridge_rx_uut.state == bridge_rx_uut.ERROR) else $error("not in error state after transmission"); #(10*`CP); diff --git a/test/bridge_tx_tb.sv b/test/bridge_tx_tb.sv index 41e4be3..0f04441 100644 --- a/test/bridge_tx_tb.sv +++ b/test/bridge_tx_tb.sv @@ -7,47 +7,45 @@ module bridge_tx_tb; // https://www.youtube.com/watch?v=WCOAr-96bGc -//boilerplate +// boilerplate logic clk; -logic rst; integer test_num; -// uart_tx <--> tb signals -logic txd; +// tb -> bridge_tx signals +logic [15:0] tb_btx_rdata; +logic res_ready; +logic tb_btx_valid; // uart_tx <--> bridge_tx signals -logic [7:0] axid; -logic axiv; -logic axir; +logic [7:0] btx_utx_data; +logic btx_utx_valid; +logic btx_utx_ready; -// bridge_tx <--> tb signals -logic res_valid; -logic res_ready; -logic [15:0] res_data; +// uart_tx -> tb signals +logic utx_tb_tx; + +bridge_tx btx ( + .clk(clk), + + .rdata_i(tb_btx_rdata), + .rw_i(1'b1), + .valid_i(tb_btx_valid), + + .data_o(btx_utx_data), + .ready_i(btx_utx_ready), + .valid_o(btx_utx_valid)); uart_tx #( - .DATA_WIDTH(8), - .CLK_FREQ_HZ(100_000_000), - .BAUDRATE(115200)) - uart_tx_uut ( - .clk(clk), - .rst(rst), - .txd(txd), - - .axiid(axid), - .axiiv(axiv), - .axiir(axir)); - -bridge_tx bridge_tx_uut( + .CLOCKS_PER_BAUD(868)) + utx ( .clk(clk), - .axiod(axid), - .axiov(axiv), - .axior(axir), + .data(btx_utx_data), + .valid(btx_utx_valid), + .busy(), + .ready(btx_utx_ready), - .res_valid(res_valid), - .res_ready(res_ready), - .res_data(res_data)); + .tx(utx_tb_tx)); always begin #`HCP @@ -60,26 +58,21 @@ initial begin // setup and reset clk = 0; - rst = 0; test_num = 0; - res_valid = 0; - res_data = 0; - #`CP - rst = 1; - #`CP - rst = 0; + tb_btx_valid = 0; + tb_btx_rdata = 0; #(10*`CP); /* ==== Test 1 Begin ==== */ $display("\n=== test 1: receive 0x0123 for baseline functionality ==="); test_num = 1; - res_data = 16'h0123; - res_valid = 1; + tb_btx_rdata = 16'h0123; + tb_btx_valid = 1; #`CP; assert(res_ready == 0) else $error("invalid handshake: res_ready held high for more than one clock cycle"); - res_valid = 0; + tb_btx_valid = 0; #(100000*`CP); /* ==== Test 1 End ==== */ @@ -87,12 +80,12 @@ initial begin /* ==== Test 2 Begin ==== */ $display("\n=== test 2: receive 0x4567 for baseline functionality ==="); test_num = 2; - res_data = 16'h4567; - res_valid = 1; + tb_btx_rdata = 16'h4567; + tb_btx_valid = 1; #`CP; assert(res_ready == 0) else $error("invalid handshake: res_ready held high for more than one clock cycle"); - res_valid = 0; + tb_btx_valid = 0; #(100000*`CP); /* ==== Test 2 End ==== */ @@ -100,12 +93,12 @@ initial begin /* ==== Test 3 Begin ==== */ $display("\n=== test 3: receive 0x89AB for baseline functionality ==="); test_num = 3; - res_data = 16'h89AB; - res_valid = 1; + tb_btx_rdata = 16'h89AB; + tb_btx_valid = 1; #`CP; assert(res_ready == 0) else $error("invalid handshake: res_ready held high for more than one clock cycle"); - res_valid = 0; + tb_btx_valid = 0; #(100000*`CP); /* ==== Test 3 End ==== */ @@ -113,12 +106,12 @@ initial begin /* ==== Test 4 Begin ==== */ $display("\n=== test 4: receive 0xCDEF for baseline functionality ==="); test_num = 4; - res_data = 16'hCDEF; - res_valid = 1; + tb_btx_rdata = 16'hCDEF; + tb_btx_valid = 1; #`CP; assert(res_ready == 0) else $error("invalid handshake: res_ready held high for more than one clock cycle"); - res_valid = 0; + tb_btx_valid = 0; #(100000*`CP); /* ==== Test 4 End ==== */ diff --git a/test/fifo_tb.sv b/test/fifo_tb.sv index 18f74f0..cf52258 100644 --- a/test/fifo_tb.sv +++ b/test/fifo_tb.sv @@ -1,5 +1,4 @@ `default_nettype none - `timescale 1ns / 1ps module fifo_tb(); diff --git a/test/manta_tb.sv b/test/manta_tb.sv deleted file mode 100644 index 34e9729..0000000 --- a/test/manta_tb.sv +++ /dev/null @@ -1,69 +0,0 @@ -`default_nettype none -`timescale 1ns / 1ps - -module manta_tb(); - logic clk; - logic rst; - logic rxd; - logic txd; - - - logic probe0, probe1, probe2; - assign probe0 = count[0]; - assign probe1 = count[1]; - assign probe2 = count[2]; - - // manta - // later make this a `MANTA that gets loaded from a svh file that the python script generates - manta #(.FIFO_DEPTH(64)) manta( - .clk(clk), - .rst(rst), - .probe0(probe0), - .probe1(probe1), - .probe2(probe2), - - .rxd(rxd), - .txd(txd)); - - /* Signal Generator */ - logic [7:0] count = 0; - always begin - count = count + 1; - #10; - end - - always begin - #5; - clk = !clk; - end - - logic [9:0] uart_data; - - initial begin - $dumpfile("manta.vcd"); - $dumpvars(0, manta_tb); - clk = 0; - rst = 1; - rxd = 1; - uart_data = 0; - #10; - rst = 0; - - // Wait a little bit to make sure that it doesn't like, explode or something - #1000; - - // send arm byte! - uart_data = {1'b1, 8'b00110000, 1'b0}; - for (int i=0; i < 10; i++) begin - rxd = uart_data[i]; - #8680; - end - - // see what happens lmao - #15000000; - - $finish(); - end -endmodule - -`default_nettype wire diff --git a/test/uart_tb.sv b/test/uart_tb.sv index d0329df..b96c597 100644 --- a/test/uart_tb.sv +++ b/test/uart_tb.sv @@ -1,5 +1,4 @@ `default_nettype none - `timescale 1ns / 1ps module uart_tb(); diff --git a/test/yeet_tb.sv b/test/yeet_tb.sv deleted file mode 100644 index b9359c6..0000000 --- a/test/yeet_tb.sv +++ /dev/null @@ -1,93 +0,0 @@ -`default_nettype none -`timescale 1ns/1ps - -`define CP 10 -`define HCP 5 - -module yeet_tb(); - logic clk; - - logic [15:0] tb_btx_rdata; - logic tb_btx_rw; - logic tb_btx_valid; - - bridge_tx btx ( - .clk(clk), - - .rdata_i(tb_btx_rdata), - .rw_i(tb_btx_rw), - .valid_i(tb_btx_valid), - - .ready_i(utx_btx_ready), - .data_o(btx_utx_data), - .valid_o(btx_utx_valid)); - - logic [7:0] btx_utx_data; - logic btx_utx_valid; - logic utx_btx_ready; - - uart_tx #(.CLOCKS_PER_BAUD(10)) utx ( - .clk(clk), - - .data(btx_utx_data), - .valid(btx_utx_valid), - .ready(utx_btx_ready), - - .tx(utx_tb_tx)); - - logic utx_tb_tx; - - logic [7:0] decoded_byte; - logic decoder_valid; - logic [7:0] decoder_data; - - always @(posedge clk) if (decoder_valid) decoded_byte <= decoder_data; - - rx_uart #(.CLOCKS_PER_BAUD(10)) urx_decoder( - .i_clk(clk), - - .i_uart_rx(utx_tb_tx), - .o_wr(decoder_valid), - .o_data(decoder_data)); - - always begin - #`HCP - clk = !clk; - end - - initial begin - $dumpfile("yeet.vcd"); - $dumpvars(0, yeet_tb); - clk = 0; - tb_btx_rdata = 0; - tb_btx_valid = 0; - tb_btx_rw = 0; - #`HCP - - #(10*`CP); - - // put some shit on the bus - tb_btx_rdata = 16'h69; - tb_btx_valid = 1; - tb_btx_rw = 0; - #`CP - tb_btx_valid = 0; - - // wait a bit - #(7000 - `CP); - - // put some more shit on the bus - tb_btx_rdata = 16'h42; - tb_btx_valid = 1; - tb_btx_rw = 1; - #`CP - tb_btx_valid = 0; - #(7000 - `CP); - - $finish(); - - end - -endmodule - -`default_nettype wire \ No newline at end of file