diff --git a/src/manta/bridge_rx.v b/src/manta/bridge_rx.v new file mode 100644 index 0000000..f978e18 --- /dev/null +++ b/src/manta/bridge_rx.v @@ -0,0 +1,130 @@ +`default_nettype none +`timescale 1ns/1ps + +module bridge_rx( + input wire clk, + input wire rst, + + input wire[7:0] axiid, + input wire axiiv, + + output reg[15:0] req_addr, + output reg[15:0] req_data, + output reg req_rw, + output reg req_valid, + input wire req_ready +); + +parameter ADDR_WIDTH = 0; +parameter DATA_WIDTH = 0; + +localparam PREAMBLE = 8'h4D; +localparam CR = 8'h0D; +localparam LF = 8'h0A; + +localparam ACQUIRE = 0; +localparam TRANSMIT = 1; +localparam ERROR = 2; + +reg [1:0] state; +reg [3:0] bytes_received; + +// no global resets! +initial begin + req_addr = 0; + req_data = 0; + req_rw = 0; + req_valid = 0; + bytes_received = 0; + state = ACQUIRE; +end + +reg [3:0] axiid_decoded; +reg axiid_is_0_thru_9; +reg axiid_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); + + 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; +end + + +always @(posedge clk) begin + if (state == ACQUIRE) begin + if(axiiv) begin + + if (bytes_received == 0) begin + if(axiid == 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; + bytes_received <= bytes_received + 1; + end + + else state <= ERROR; + end + + else if( bytes_received == 5) begin + if( (axiid == CR) | (axiid == LF)) begin + req_valid <= 1; + req_rw = 0; + bytes_received <= 0; + state <= TRANSMIT; + end + + else if (axiid_is_0_thru_9 | axiid_is_A_thru_F) begin + bytes_received <= bytes_received + 1; + req_data <= (req_data << 4) | axiid_decoded; + end + + else state <= ERROR; + end + + 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; + bytes_received <= bytes_received + 1; + end + + else state <= ERROR; + end + + else if (bytes_received == 9) begin + bytes_received <= 0; + if( (axiid == CR) | (axiid == LF)) begin + req_valid <= 1; + req_rw <= 1; + state <= TRANSMIT; + end + + else state <= ERROR; + end + end + end + + + else if (state == TRANSMIT) begin + if(req_ready) begin + req_valid <= 0; + state <= ACQUIRE; + end + + if(axiiv) begin + if ( (axiid != CR) & (axiid != LF)) begin + req_valid <= 0; + state <= ERROR; + end + end + end +end + +endmodule +`default_nettype wire \ No newline at end of file diff --git a/src/manta/bridge_tx.v b/src/manta/bridge_tx.v new file mode 100644 index 0000000..2bfd895 --- /dev/null +++ b/src/manta/bridge_tx.v @@ -0,0 +1,93 @@ +`default_nettype none +`timescale 1ns/1ps + +module bridge_tx( + input wire clk, + + output reg [7:0] axiod, + output reg axiov, + input wire axior, + + input wire [15:0] res_data, + input wire res_valid, + output reg res_ready +); + +parameter ADDR_WIDTH = 0; +parameter DATA_WDITH = 0; + +localparam PREAMBLE = 8'h4D; +localparam CR = 8'h0D; +localparam LF = 8'h0A; + +reg [3:0] bytes_transmitted; +reg [15:0] buffer; + +initial begin + axiod = 0; + axiov = 0; + res_ready = 1; + bytes_transmitted = 0; + buffer = 0; +end + +always @(posedge clk) begin + if (res_ready) begin + if(res_valid) begin + buffer <= res_data; + res_ready <= 0; + bytes_transmitted <= 0; + axiod <= PREAMBLE; + axiov <= 1; + end + end + + else begin + if (bytes_transmitted == 0) begin + if(axior) bytes_transmitted <= 1; + end + + if (bytes_transmitted == 1) begin + axiod <= (buffer[15:12] < 10) ? (buffer[15:12] + 8'h30) : (buffer[15:12] + 8'h41 - 'd10); + if (axior) bytes_transmitted <= 2; + end + + else if(bytes_transmitted == 2) begin + axiod <= (buffer[11:8] < 10) ? (buffer[11:8] + 8'h30) : (buffer[11:8] + 8'h41 - 'd10); + if (axior) bytes_transmitted <= 3; + end + + else if(bytes_transmitted == 3) begin + axiod <= (buffer[7:4] < 10) ? (buffer[7:4] + 8'h30) : (buffer[7:4] + 8'h41 - 'd10); + if (axior) bytes_transmitted <= 4; + end + + else if(bytes_transmitted == 4) begin + axiod <= (buffer[3:0] < 10) ? (buffer[3:0] + 8'h30) : (buffer[3:0] + 8'h41 - 'd10); + if (axior) bytes_transmitted <= 5; + end + + else if(bytes_transmitted == 5) begin + axiod <= 8'h0D; + if (axior) bytes_transmitted <= 6; + end + + else if(bytes_transmitted == 6) begin + axiod <= 8'h0A; + if (axior) begin + axiov <= 0; + bytes_transmitted <= 7; + end + end + + else if(bytes_transmitted == 7) begin + if(axior) begin + res_ready <= 1; + bytes_transmitted <= 0; + end + end + end +end + +endmodule +`default_nettype wire \ No newline at end of file diff --git a/src/manta/lut_ram.v b/src/manta/lut_ram.v new file mode 100644 index 0000000..6c036f6 --- /dev/null +++ b/src/manta/lut_ram.v @@ -0,0 +1,70 @@ +`default_nettype none +`timescale 1ns/1ps + +module lut_ram( + input wire clk, + + // input port + input wire req_addr_i, + input wire req_data_i, + input wire req_rw_i, + input wire req_valid_i, + output reg req_ready_o + + input wire res_data_i, + input wire res_valid_i, + output reg res_ready_o + + // output port + output reg req_addr_o, + output reg req_data_o, + output reg req_rw_o, + output reg req_valid_o, + input wire req_ready_i, + + output reg res_data_o, + output reg res_valid_o, + input wire res_ready_i +); + +localparam BASE_ADDR = 0; +localparam DEPTH = 8; +localparam TOP_ADDR = BASE_ADDR + DEPTH - 1; + +reg [15:0] [DEPTH-1:0] mem; + +initial begin + req_ready_o = 1; +end + +always @(posedge clk) begin + if( (req_addr_i < BASE_ADDR) || (req_addr_i > TOP_ADDR) ) begin + req_addr_o <= req_addr_i; + req_data_o <= req_data_i; + req_rw_o <= req_rw_i; + req_valid_o <= req_valid_i; + req_ready_o <= req_ready_i; + + res_data_o <= res_data_i; + res_valid_o <= res_valid_i; + res_ready_o <= res_ready_i; + end + + else begin + req_ready <= 1; + + + if (req_valid_i) begin + if (req_rw_i) mem[req_addr_i - BASE_ADDR] <= req_data_i; + + else begin + + end + end + end +end + +endmodule + + +`default_nettype wire \ No newline at end of file diff --git a/src/manta/uart_rx.sv b/src/manta/uart_rx.v similarity index 55% rename from src/manta/uart_rx.sv rename to src/manta/uart_rx.v index 420959f..298bc66 100644 --- a/src/manta/uart_rx.sv +++ b/src/manta/uart_rx.v @@ -6,35 +6,32 @@ module uart_rx( input wire rst, input wire rxd, - output logic [DATA_WIDTH - 1:0] data, - output logic ready, - output logic busy + output reg [DATA_WIDTH - 1:0] axiod, + output reg axiov ); - - // Just going to stick to 8N1 for now, we'll come back and - // parameterize this later. - parameter DATA_WIDTH = 8; - parameter CLK_FREQ_HZ = 100_000_000; - parameter BAUDRATE = 115200; + parameter DATA_WIDTH = 0; + parameter CLK_FREQ_HZ = 0; + parameter BAUDRATE = 0; - localparam PRESCALER = CLK_FREQ_HZ / BAUDRATE; + localparam BAUD_PERIOD = CLK_FREQ_HZ / BAUDRATE; - logic [$clog2(PRESCALER) - 1:0] baud_counter; - logic [$clog2(DATA_WIDTH + 2):0] bit_index; - logic [DATA_WIDTH + 2 : 0] data_buf; + reg [$clog2(BAUD_PERIOD) - 1:0] baud_counter; + reg [$clog2(DATA_WIDTH + 2):0] bit_index; + reg [DATA_WIDTH + 2 : 0] data_buf; - logic prev_rxd; + reg prev_rxd; + reg busy; always_ff @(posedge clk) begin prev_rxd <= rxd; - ready <= 0; - baud_counter <= (baud_counter == PRESCALER - 1) ? 0 : baud_counter + 1; + axiov <= 0; + baud_counter <= (baud_counter == BAUD_PERIOD - 1) ? 0 : baud_counter + 1; // reset logic if(rst) begin bit_index <= 0; - data <= 0; + axiod <= 0; busy <= 0; baud_counter <= 0; end @@ -48,7 +45,7 @@ module uart_rx( // if we're actually receiving else if (busy) begin - if (baud_counter == PRESCALER / 2) begin + if (baud_counter == BAUD_PERIOD / 2) begin data_buf[bit_index] <= rxd; bit_index <= bit_index + 1; @@ -58,8 +55,8 @@ module uart_rx( if (rxd && ~data_buf[0]) begin - data <= data_buf[DATA_WIDTH : 1]; - ready <= 1; + axiod <= data_buf[DATA_WIDTH : 1]; + axiov <= 1; end end end diff --git a/src/manta/uart_tx.sv b/src/manta/uart_tx.v similarity index 60% rename from src/manta/uart_tx.sv rename to src/manta/uart_tx.v index cdc921f..554d087 100644 --- a/src/manta/uart_tx.sv +++ b/src/manta/uart_tx.v @@ -1,39 +1,39 @@ `default_nettype none `timescale 1ns / 1ps - module uart_tx( input wire clk, input wire rst, - input wire [DATA_WIDTH-1:0] data, - input wire start, - output logic busy, - output logic txd + input wire [DATA_WIDTH-1:0] axiid, + input wire axiiv, + output reg axiir, + + output reg txd ); - - // Just going to stick to 8N1 for now, we'll come back and - // parameterize this later. - parameter DATA_WIDTH = 8; - parameter CLK_FREQ_HZ = 100_000_000; - parameter BAUDRATE = 115200; + parameter DATA_WIDTH = 0; + parameter CLK_FREQ_HZ = 0; + parameter BAUDRATE = 0; - localparam PRESCALER = CLK_FREQ_HZ / BAUDRATE; + localparam BAUD_PERIOD = CLK_FREQ_HZ / BAUDRATE; - logic [$clog2(PRESCALER) - 1:0] baud_counter; - logic [$clog2(DATA_WIDTH + 2):0] bit_index; - logic [DATA_WIDTH - 1:0] data_buf; + reg busy; + assign axiir = ~busy; + + reg [$clog2(BAUD_PERIOD) - 1:0] baud_counter; + reg [$clog2(DATA_WIDTH + 2):0] bit_index; + reg [DATA_WIDTH - 1:0] data_buf; // make secondary logic for baudrate - always_ff @(posedge clk) begin + always @(posedge clk) begin if(rst) baud_counter <= 0; else begin - baud_counter <= (baud_counter == PRESCALER - 1) ? 0 : baud_counter + 1; + baud_counter <= (baud_counter == BAUD_PERIOD - 1) ? 0 : baud_counter + 1; end end - always_ff @(posedge clk) begin + always @(posedge clk) begin // reset logic if(rst) begin @@ -45,9 +45,9 @@ module uart_tx( // enter transmitting state logic // don't allow new requests to interrupt current // transfers - if(start && ~busy) begin + if(axiiv && ~busy) begin busy <= 1; - data_buf <= data; + data_buf <= axiid; end diff --git a/src/manta/uplink.sv b/src/manta/uplink.sv deleted file mode 100644 index 276c211..0000000 --- a/src/manta/uplink.sv +++ /dev/null @@ -1,96 +0,0 @@ -`default_nettype none - -`define IDLE 0 -`define RUN 1 - -module uplink( - input wire clk, - input wire rst, - input wire start, - output wire busy, - - /* Begin autogenerated probe definitions */ - output wire alice, - output wire [2:0] bob, - output wire charlotte, - output wire [3:0] donovan - /* End autogenerated probe definitions */ - ); - - /* - this works in a very simple way - all it does is chill - in the idle state, until a request to start uplinking is - received. when that happens, it'll start dumping things - from the port until the BRAM is empty, and then that's it. - - this dumping happens with the trigger condition - the clock - cycle that the triggr goes high on, we should output data. - or have the option to, with some kind of holdoff. - - oh wait this might be a little hard since we've got the two - clock cycles of latency on the BRAM, so we actually need to - preload the first two values of the bram into registers so - when it's time to go - - actually it's probably worth thinking more about how useful - this would acatully be, because right now i'm not seeing too - many situations where i'd want to use this. and we can always - come back to it - */ - - parameter WIDTH = 0; - parameter DEPTH = 0; - localparam AW = $clog2(DEPTH); - - logic [AW:0] read_pointer; - logic state; - - always_ff @(posedge clk) begin - if(rst) begin - state <= `IDLE - read_pointer <= 0; - end - - else begin - if(state == `IDLE) begin - // do nothing, just wait for trigger condition - if(start) state <= `RUN; - end - - if(state == `RUN) begin - - end - end - end - - xilinx_true_dual_port_read_first_2_clock_ram #( - .RAM_WIDTH(), - .RAM_DEPTH(), - .RAM_PERFORMANCE("HIGH PERFORMANCE") - - ) buffer ( - - // write port (currently unused) - .clka(clk), - .rsta(rst), - .ena(1), - .addra(0), - .dina(0), - .wea(0), - .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 \ No newline at end of file diff --git a/test/bridge_rx_tb.sv b/test/bridge_rx_tb.sv new file mode 100644 index 0000000..bfed07d --- /dev/null +++ b/test/bridge_rx_tb.sv @@ -0,0 +1,287 @@ +`default_nettype none +`timescale 1ns/1ps + +`define CP 10 +`define HCP 5 + +`define SEND_MESSAGE(MESSAGE) \ + uart_rx_axiov = 1; \ + for(int i=0; i < $size(MESSAGE); i++) begin \ + uart_rx_axiod = MESSAGE[i]; \ + #`CP; \ + end \ + uart_rx_axiov = 0; \ + +module bridge_rx_tb; +// https://www.youtube.com/watch?v=WCOAr-96bGc + +//boilerplate +logic clk; +logic rst; +string message; +integer test_num; + +// uart inputs and outputs +logic rxd; +logic [7:0] uart_rx_axiod; +logic uart_rx_axiov; + +// 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 req_ready; + +bridge_rx bridge_rx_uut( + .clk(clk), + .rst(rst), + + // connect to uart_rx + .axiid(uart_rx_axiod), + .axiiv(uart_rx_axiov), + + .req_addr(req_addr), + .req_data(req_data), + .req_rw(req_rw), + .req_valid(req_valid), + .req_ready(req_ready)); + +always begin + #`HCP + clk = !clk; +end + +initial begin + $dumpfile("bridge_rx.vcd"); + $dumpvars(0, bridge_rx_tb); + + // setup and reset + clk = 0; + rst = 0; + uart_rx_axiod = 0; + uart_rx_axiov = 0; + req_ready = 1; + test_num = 0; + #`CP + rst = 1; + #`CP + rst = 0; + + /* ==== Test 1 Begin ==== */ + $display("\n=== test 1: transmit M12345678(CR)(LF) for baseline functionality ==="); + test_num = 1; + 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(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state after transmission"); + + #(10*`CP); + /* ==== Test 1 End ==== */ + + + /* ==== Test 2 Begin ==== */ + $display("\n=== test 2: transmit MDEADBEEF(CR)(LF) for proper state reset ==="); + test_num = 2; + assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission"); + 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(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state after transmission"); + + #(10*`CP); + /* ==== Test 2 End ==== */ + + + /* ==== Test 3 Begin ==== */ + $display("\n=== test 3: transmit MBABE(CR)(LF) for baseline functionality ==="); + test_num = 3; + assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission"); + 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(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state after transmission"); + + #(10*`CP); + /* ==== Test 3 End ==== */ + + /* ==== Test 4 Begin ==== */ + $display("\n=== test 4: transmit M0000(CR) for EOL insensitivity ==="); + test_num = 4; + assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission"); + 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(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state after transmission"); + + #(10*`CP); + /* ==== Test 4 End ==== */ + + /* ==== Test 5 Begin ==== */ + $display("\n=== test 5: transmit M1234(LF) for EOL insensitivity ==="); + test_num = 5; + assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission"); + 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(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state after transmission"); + + #(10*`CP); + /* ==== Test 5 End ==== */ + + /* ==== Test 6 Begin ==== */ + $display("\n=== test 6: transmit MF00DBEEF(CR) for EOL insensitivity ==="); + test_num = 6; + assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission"); + 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(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state after transmission"); + + #(10*`CP); + /* ==== Test 6 End ==== */ + + /* ==== Test 7 Begin ==== */ + $display("\n=== test 7: transmit MB0BACAFE(LF) for EOL insensitivity ==="); + test_num = 7; + assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission"); + 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(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state after transmission"); + + #(10*`CP); + /* ==== Test 7 End ==== */ + + /* ==== Test 8 Begin ==== */ + $display("\n\nIntentionally bad messages:"); + $display("\n=== test 8: transmit MABC(CR)(LF) for message length ==="); + test_num = 8; + assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission"); + message = {"MABC", 8'h0D, 8'h0A}; + `SEND_MESSAGE(message) + + assert(req_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); + /* ==== Test 8 End ==== */ + + /* ==== Test 9 Begin ==== */ + $display("\n=== test 9: transmit M12345(CR)(LF) for message length ==="); + test_num = 9; + bridge_rx_uut.state = bridge_rx_uut.ACQUIRE; + bridge_rx_uut.bytes_received = 0; + assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission"); + message = {"MABC", 8'h0D, 8'h0A}; + `SEND_MESSAGE(message) + + assert(req_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); + /* ==== Test 9 End ==== */ + + /* ==== Test 10 Begin ==== */ + $display("\n=== test 10: transmit M(CR)(LF) for message length ==="); + test_num = 10; + bridge_rx_uut.state = bridge_rx_uut.ACQUIRE; + bridge_rx_uut.bytes_received = 0; + assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission"); + message = {"MABC", 8'h0D, 8'h0A}; + `SEND_MESSAGE(message) + + assert(req_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); + /* ==== Test 10 End ==== */ + + /* ==== Test 11 Begin ==== */ + $display("\n=== test 11: transmit M123456789101112131415161718191201222(CR)(LF) for message length ==="); + test_num = 11; + bridge_rx_uut.state = bridge_rx_uut.ACQUIRE; + bridge_rx_uut.bytes_received = 0; + assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission"); + message = {"MABC", 8'h0D, 8'h0A}; + `SEND_MESSAGE(message) + + assert(req_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); + /* ==== Test 11 End ==== */ + + /* ==== Test 12 Begin ==== */ + $display("\n=== test 12: transmit MABCG(CR)(LF) for invalid characters ==="); + test_num = 12; + bridge_rx_uut.state = bridge_rx_uut.ACQUIRE; + bridge_rx_uut.bytes_received = 0; + assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission"); + message = {"MABCG", 8'h0D, 8'h0A}; + `SEND_MESSAGE(message) + + assert(req_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); + /* ==== Test 12 End ==== */ + + /* ==== Test 13 Begin ==== */ + $display("\n=== test 13: transmit MABC[]()##*@(CR)(LF) for invalid characters and message length ==="); + test_num = 13; + bridge_rx_uut.state = bridge_rx_uut.ACQUIRE; + bridge_rx_uut.bytes_received = 0; + assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission"); + message = {"MABC[]()##*@", 8'h0D, 8'h0A}; + `SEND_MESSAGE(message) + + assert(req_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); + /* ==== Test 13 End ==== */ + + /* ==== Test 14 Begin ==== */ + $display("\n=== test 14: transmit M(CR)(LF) for message length ==="); + test_num = 14; + bridge_rx_uut.state = bridge_rx_uut.ACQUIRE; + bridge_rx_uut.bytes_received = 0; + assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission"); + message = {"M", 8'h0D, 8'h0A}; + `SEND_MESSAGE(message) + + assert(req_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); + /* ==== Test 14 End ==== */ + + $finish(); +end + + +endmodule +`default_nettype wire \ No newline at end of file diff --git a/test/bridge_tx_tb.sv b/test/bridge_tx_tb.sv new file mode 100644 index 0000000..41e4be3 --- /dev/null +++ b/test/bridge_tx_tb.sv @@ -0,0 +1,132 @@ +`default_nettype none +`timescale 1ns/1ps + +`define CP 10 +`define HCP 5 + +module bridge_tx_tb; +// https://www.youtube.com/watch?v=WCOAr-96bGc + +//boilerplate +logic clk; +logic rst; +integer test_num; + +// uart_tx <--> tb signals +logic txd; + +// uart_tx <--> bridge_tx signals +logic [7:0] axid; +logic axiv; +logic axir; + +// bridge_tx <--> tb signals +logic res_valid; +logic res_ready; +logic [15:0] res_data; + +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( + .clk(clk), + + .axiod(axid), + .axiov(axiv), + .axior(axir), + + .res_valid(res_valid), + .res_ready(res_ready), + .res_data(res_data)); + +always begin + #`HCP + clk = !clk; +end + +initial begin + $dumpfile("bridge_tx.vcd"); + $dumpvars(0, bridge_tx_tb); + + // setup and reset + clk = 0; + rst = 0; + test_num = 0; + + res_valid = 0; + res_data = 0; + #`CP + rst = 1; + #`CP + rst = 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; + + #`CP; + assert(res_ready == 0) else $error("invalid handshake: res_ready held high for more than one clock cycle"); + res_valid = 0; + + #(100000*`CP); + /* ==== Test 1 End ==== */ + + /* ==== Test 2 Begin ==== */ + $display("\n=== test 2: receive 0x4567 for baseline functionality ==="); + test_num = 2; + res_data = 16'h4567; + res_valid = 1; + + #`CP; + assert(res_ready == 0) else $error("invalid handshake: res_ready held high for more than one clock cycle"); + res_valid = 0; + + #(100000*`CP); + /* ==== Test 2 End ==== */ + + /* ==== Test 3 Begin ==== */ + $display("\n=== test 3: receive 0x89AB for baseline functionality ==="); + test_num = 3; + res_data = 16'h89AB; + res_valid = 1; + + #`CP; + assert(res_ready == 0) else $error("invalid handshake: res_ready held high for more than one clock cycle"); + res_valid = 0; + + #(100000*`CP); + /* ==== Test 3 End ==== */ + + /* ==== Test 4 Begin ==== */ + $display("\n=== test 4: receive 0xCDEF for baseline functionality ==="); + test_num = 4; + res_data = 16'hCDEF; + res_valid = 1; + + #`CP; + assert(res_ready == 0) else $error("invalid handshake: res_ready held high for more than one clock cycle"); + res_valid = 0; + + #(100000*`CP); + /* ==== Test 4 End ==== */ + + $finish(); +end + + +endmodule + +`default_nettype wire \ No newline at end of file diff --git a/test/bus_tb.sv b/test/bus_tb.sv new file mode 100644 index 0000000..534fa9d --- /dev/null +++ b/test/bus_tb.sv @@ -0,0 +1,106 @@ +`default_nettype none +`timescale 1ns/1ps + +module bus_tb; +// https://www.youtube.com/watch?v=WCOAr-96bGc + +//boilerplate +logic clk; +logic rst; + +// uart inputs and outputs +logic rxd; +logic [7:0] uart_rx_axiod; +logic uart_rx_axiov; + +logic txd; +logic [7:0] uart_tx_axiid; +logic uart_tx_axiiv; +logic uart_tx_axiir; + +// the parameter will all get filled out in manta's big instantiator thing hehehee +parameter ADDR_WIDTH = 0; // $clog2( how much memory we need rounded up to the nearest 8 ) +parameter DATA_WIDTH = 0; + +// 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 req_ready; + +// response bus, get connected to uart_tx (through a FSM, but the data's there in spirit) +logic res_valid; +logic res_ready; +logic res_data; + +uart_rx #( + .DATA_WDITH(8), + .CLK_FREQ_HZ(100_000_000), + .BAUDRATE(115200)) + uart_rx_uut ( + .clk(clk), + .rst(rst), + .rxd(rxd), + + .axiod(uart_rx_axiod), + .axiov(uart_rx_axiov)); + +uart_tx #( + .DATA_WDITH(8), + .CLK_FREQ_HZ(100_000_000), + .BAUDRATE(115200)) + uart_tx_uut ( + .clk(clk), + .rst(rst), + .txd(txd), + + .axiid(uart_tx_axiid), + .axiiv(uart_tx_axiiv), + .axiir(uart_tx_axiir)); + +bridge_rx bridge_rx_uut( + .clk(clk), + .rst(rst), + + // connect to uart_rx + .axiid(uart_rx_axiod), + .axiiv(uart_rx_axiov), + + .req_addr(req_addr), + .req_data(req_data), + .req_rw(req_rw), + .req_valid(req_valid), + .req_ready(req_ready)); + +bridge_tx bridge_tx_uut( + .clk(clk), + .rst(rst), + + // connect to uart_tx + .axiod(uart_tx_axiid), + .axiov(uart_tx_axiiv), + .axior(uart_tx_axiir), + + .res_valid(res_valid), + .res_ready(res_ready), + .res_data(res_data)); + +always begin + #5; + clk = !clk; +end + +initial begin + $dumpfile("bus.vcd"); + $dumpvars(0, bus_tb); + + +end + + +endmodule + + + +`default_nettype wire \ No newline at end of file