diff --git a/lut_mem.gtkw b/lut_mem.gtkw new file mode 100644 index 0000000..c684be5 --- /dev/null +++ b/lut_mem.gtkw @@ -0,0 +1,67 @@ +[*] +[*] GTKWave Analyzer v3.3.107 (w)1999-2020 BSI +[*] Tue Feb 28 22:40:21 2023 +[*] +[dumpfile] "/Users/fischerm/fpga/manta/lut_mem.vcd" +[dumpfile_mtime] "Tue Feb 28 22:39:27 2023" +[dumpfile_size] 5116 +[savefile] "/Users/fischerm/fpga/manta/lut_mem.gtkw" +[timestart] 0 +[size] 1710 994 +[pos] -1 -1 +*-45.675117 63700000000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] lut_mem_tb. +[sst_width] 193 +[signals_width] 308 +[sst_expanded] 1 +[sst_vpaned_height] 305 +@28 +lut_mem_tb.clk +@200 +- +-tb --> mem_1 +@28 +lut_mem_tb.tb_mem_1_valid +@22 +lut_mem_tb.tb_mem_1_addr[15:0] +lut_mem_tb.tb_mem_1_wdata[15:0] +lut_mem_tb.tb_mem_1_rdata[15:0] +@28 +lut_mem_tb.tb_mem_1_rw +@200 +- +-mem_1 --> mem_2 +@28 +lut_mem_tb.mem_1_mem_2_valid +@22 +lut_mem_tb.mem_1_mem_2_addr[15:0] +lut_mem_tb.mem_1_mem_2_wdata[15:0] +lut_mem_tb.mem_1_mem_2_rdata[15:0] +@28 +lut_mem_tb.mem_1_mem_2_rw +@200 +- +- +-mem_2 --> mem_3 +@28 +lut_mem_tb.mem_2_mem_3_valid +@22 +lut_mem_tb.mem_2_mem_3_addr[15:0] +lut_mem_tb.mem_2_mem_3_wdata[15:0] +lut_mem_tb.mem_2_mem_3_rdata[15:0] +@28 +lut_mem_tb.mem_2_mem_3_rw +@200 +- +- +-mem_3 --> tb +@28 +lut_mem_tb.mem_3_tb_valid +@22 +lut_mem_tb.mem_3_tb_addr[15:0] +lut_mem_tb.mem_3_tb_wdata[15:0] +lut_mem_tb.mem_3_tb_rdata[15:0] +@28 +lut_mem_tb.mem_3_tb_rw +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/src/manta/fifo.sv b/src/manta/fifo.v similarity index 80% rename from src/manta/fifo.sv rename to src/manta/fifo.v index 8abd3c3..6a90a67 100644 --- a/src/manta/fifo.sv +++ b/src/manta/fifo.v @@ -9,35 +9,35 @@ module fifo ( input wire input_ready, input wire request_output, - output logic [WIDTH - 1:0] data_out, - output logic output_valid, + output reg [WIDTH - 1:0] data_out, + output reg output_valid, - output logic [AW:0] size, - output logic empty, - output logic full + output reg [AW:0] size, + output reg empty, + output reg full ); parameter WIDTH = 8; parameter DEPTH = 4096; localparam AW = $clog2(DEPTH); - logic [AW:0] write_pointer; - logic [AW:0] read_pointer; + reg [AW:0] write_pointer; + reg [AW:0] read_pointer; - logic empty_int; + reg empty_int; assign empty_int = (write_pointer[AW] == read_pointer[AW]); - logic full_or_empty; + 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; - logic output_valid_pip_0; - logic output_valid_pip_1; + reg output_valid_pip_0; + reg output_valid_pip_1; - always_ff @(posedge clk) begin + always @(posedge clk) begin if (input_ready && ~full) write_pointer <= write_pointer + 1'd1; diff --git a/src/manta/lut_mem.v b/src/manta/lut_mem.v new file mode 100644 index 0000000..74dcb3d --- /dev/null +++ b/src/manta/lut_mem.v @@ -0,0 +1,64 @@ +`default_nettype none +`timescale 1ns/1ps + +module lut_mem( + input wire clk, + + // input port + input wire [15:0] addr_i, + input wire [15:0] wdata_i, + input wire [15:0] rdata_i, + input wire rw_i, + input wire valid_i, + + // output port + output reg [15:0] addr_o, + output reg [15:0] wdata_o, + output reg [15:0] rdata_o, + output reg rw_o, + output reg valid_o +); + + +parameter DEPTH = 8; +parameter BASE_ADDR = 0; +reg [DEPTH-1:0][15:0] mem; + +reg [15:0] addr_ppln; +reg [15:0] wdata_ppln; +reg [15:0] rdata_ppln; +reg rw_ppln; +reg valid_ppln; + +always @(posedge clk) begin + + // pipeline stage 1 + addr_ppln <= addr_i; + wdata_ppln <= wdata_i; + rdata_ppln <= rdata_i; + rw_ppln <= rw_i; + valid_ppln <= valid_i; + + // pipeline stage 2 + addr_o <= addr_ppln; + wdata_o <= wdata_ppln; + rdata_o <= rdata_ppln; + rw_o <= rw_ppln; + valid_o <= valid_ppln; + + + if(valid_i) begin + // write to memory + if( (addr_i >= BASE_ADDR) && (addr_i <= BASE_ADDR + DEPTH - 1) ) begin + + // write to mem + if (rw_i) mem[addr_i - BASE_ADDR] <= wdata_i; + + // read from mem + else rdata_ppln <= mem[addr_i - BASE_ADDR]; + 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 deleted file mode 100644 index 6c036f6..0000000 --- a/src/manta/lut_ram.v +++ /dev/null @@ -1,70 +0,0 @@ -`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/manta_template.sv b/src/manta/manta_template.v similarity index 90% rename from src/manta/manta_template.sv rename to src/manta/manta_template.v index e4f7c40..f469dfe 100644 --- a/src/manta/manta_template.sv +++ b/src/manta/manta_template.v @@ -24,7 +24,7 @@ module manta ( /* End autogenerated probe definitions */ input wire rxd, - output logic txd); + output reg txd); /* Begin autogenerated parameters */ localparam SAMPLE_WIDTH = @SAMPLE_WIDTH; @@ -34,25 +34,25 @@ module manta ( localparam BAUDRATE = @BAUDRATE; localparam CLK_FREQ_HZ = @CLK_FREQ_HZ; - logic trigger; + reg trigger; assign trigger = @TRIGGER; - logic [SAMPLE_WIDTH - 1 : 0] concat; + reg [SAMPLE_WIDTH - 1 : 0] concat; assign concat = @CONCAT; /* End autogenerated parameters */ // FIFO - logic [7:0] fifo_data_in; - logic fifo_input_ready; + reg [7:0] fifo_data_in; + reg fifo_input_ready; - logic fifo_request_output; - logic [7:0] fifo_data_out; - logic fifo_output_valid; + reg fifo_request_output; + reg [7:0] fifo_data_out; + reg fifo_output_valid; - logic [11:0] fifo_size; - logic fifo_empty; - logic fifo_full; + reg [11:0] fifo_size; + reg fifo_empty; + reg fifo_full; fifo #( .WIDTH(SAMPLE_WIDTH), @@ -73,13 +73,13 @@ module manta ( .full(fifo_full)); // Serial interface - logic tx_start; - logic [7:0] tx_data; - logic tx_busy; + reg tx_start; + reg [7:0] tx_data; + reg tx_busy; - logic [7:0] rx_data; - logic rx_ready; - logic rx_busy; + reg [7:0] rx_data; + reg rx_ready; + reg rx_busy; uart_tx #( @@ -138,10 +138,10 @@ module manta ( */ - logic [1:0] state; - logic [2:0] downlink_fsm_state; + reg [1:0] state; + reg [2:0] downlink_fsm_state; - always_ff @(posedge clk) begin + always @(posedge clk) begin if(rst) begin state <= `IDLE; downlink_fsm_state <= 0; diff --git a/test/lut_mem_tb.sv b/test/lut_mem_tb.sv new file mode 100644 index 0000000..95e13db --- /dev/null +++ b/test/lut_mem_tb.sv @@ -0,0 +1,207 @@ +`default_nettype none + +`define CP 10 +`define HCP 5 + +module lut_mem_tb; + // https://www.youtube.com/watch?v=WCOAr-96bGc + + //boilerplate + logic clk; + integer test_num; + + // tb --> mem_1 signals + logic [15:0] tb_mem_1_addr; + logic [15:0] tb_mem_1_wdata; + logic [15:0] tb_mem_1_rdata; + logic tb_mem_1_rw; + logic tb_mem_1_valid; + + lut_mem #( + .DEPTH(8), + .BASE_ADDR(0) + ) mem_1 ( + .clk(clk), + .addr_i(tb_mem_1_addr), + .wdata_i(tb_mem_1_wdata), + .rdata_i(tb_mem_1_rdata), + .rw_i(tb_mem_1_rw), + .valid_i(tb_mem_1_valid), + + .addr_o(mem_1_mem_2_addr), + .wdata_o(mem_1_mem_2_wdata), + .rdata_o(mem_1_mem_2_rdata), + .rw_o(mem_1_mem_2_rw), + .valid_o(mem_1_mem_2_valid) + ); + + // mem_1 --> mem_2 signals + logic [15:0] mem_1_mem_2_addr; + logic [15:0] mem_1_mem_2_wdata; + logic [15:0] mem_1_mem_2_rdata; + logic mem_1_mem_2_rw; + logic mem_1_mem_2_valid; + + lut_mem #( + .DEPTH(8), + .BASE_ADDR(8) + ) mem_2 ( + .clk(clk), + .addr_i(mem_1_mem_2_addr), + .wdata_i(mem_1_mem_2_wdata), + .rdata_i(mem_1_mem_2_rdata), + .rw_i(mem_1_mem_2_rw), + .valid_i(mem_1_mem_2_valid), + + .addr_o(mem_2_mem_3_addr), + .wdata_o(mem_2_mem_3_wdata), + .rdata_o(mem_2_mem_3_rdata), + .rw_o(mem_2_mem_3_rw), + .valid_o(mem_2_mem_3_valid) + ); + + // mem_2 --> mem_3 signals + logic [15:0] mem_2_mem_3_addr; + logic [15:0] mem_2_mem_3_wdata; + logic [15:0] mem_2_mem_3_rdata; + logic mem_2_mem_3_rw; + logic mem_2_mem_3_valid; + + lut_mem #( + .DEPTH(8), + .BASE_ADDR(16) + ) mem_3 ( + .clk(clk), + .addr_i(mem_2_mem_3_addr), + .wdata_i(mem_2_mem_3_wdata), + .rdata_i(mem_2_mem_3_rdata), + .rw_i(mem_2_mem_3_rw), + .valid_i(mem_2_mem_3_valid), + + .addr_o(mem_3_tb_addr), + .wdata_o(mem_3_tb_wdata), + .rdata_o(mem_3_tb_rdata), + .rw_o(mem_3_tb_rw), + .valid_o(mem_3_tb_valid) + ); + + // mem_3 --> tb signals + logic [15:0] mem_3_tb_addr; + logic [15:0] mem_3_tb_wdata; + logic [15:0] mem_3_tb_rdata; + logic mem_3_tb_rw; + logic mem_3_tb_valid; + + always begin + #`HCP + clk = !clk; + end + + initial begin + $dumpfile("lut_mem.vcd"); + $dumpvars(0, lut_mem_tb); + + // setup and reset + clk = 0; + test_num = 0; + #`HCP + + // throw some nonzero data in the memories just so we know that we're pulling from the right ones + mem_1.mem[0] = 16'h0000; + mem_1.mem[1] = 16'h0001; + mem_1.mem[2] = 16'h0002; + mem_1.mem[3] = 16'h0003; + mem_1.mem[4] = 16'h0004; + mem_1.mem[5] = 16'h0005; + mem_1.mem[6] = 16'h0006; + mem_1.mem[7] = 16'h0007; + + mem_2.mem[0] = 16'h0008; + mem_2.mem[1] = 16'h0009; + mem_2.mem[2] = 16'h000A; + mem_2.mem[3] = 16'h000B; + mem_2.mem[4] = 16'h000C; + mem_2.mem[5] = 16'h000D; + mem_2.mem[6] = 16'h000E; + mem_2.mem[7] = 16'h000F; + + mem_3.mem[0] = 16'h0010; + mem_3.mem[1] = 16'h0011; + mem_3.mem[2] = 16'h0012; + mem_3.mem[3] = 16'h0013; + mem_3.mem[4] = 16'h0014; + mem_3.mem[5] = 16'h0015; + mem_3.mem[6] = 16'h0016; + mem_3.mem[7] = 16'h0017; + + tb_mem_1_addr = 0; + tb_mem_1_wdata = 0; + tb_mem_1_rdata = 0; + tb_mem_1_rw = 0; + tb_mem_1_valid = 0; + + #(10*`CP); + + /* ==== Test 1 Begin ==== */ + $display("\n=== test 1: read from 0x0001 for baseline functionality ==="); + test_num = 1; + + // TODO: make this check that all bus outputs are 0 + + // 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"); + + tb_mem_1_addr = 16'h0001; + tb_mem_1_valid = 1; + tb_mem_1_rw = 0; + #`CP; + tb_mem_1_valid = 0; + + #(10*`CP); + /* ==== Test 1 End ==== */ + + /* ==== Test 2 Begin ==== */ + $display("\n=== test 2: read from 0x0012 for baseline functionality ==="); + test_num = 2; + + tb_mem_1_addr = 16'h0012; + tb_mem_1_valid = 1; + tb_mem_1_rw = 0; + #`CP; + tb_mem_1_valid = 0; + #(10*`CP); + /* ==== Test 2 End ==== */ + + /* ==== Test 3 Begin ==== */ + $display("\n=== test 3: write to 0x0012 for baseline functionality ==="); + test_num = 3; + + tb_mem_1_addr = 16'h0012; + tb_mem_1_wdata = 16'h0069; + tb_mem_1_valid = 1; + tb_mem_1_rw = 1; + #`CP; + tb_mem_1_valid = 0; + tb_mem_1_rw = 0; + #(10*`CP); + /* ==== Test 3 End ==== */ + + /* ==== Test 4 Begin ==== */ + $display("\n=== test 4: read from 0x0012 for baseline functionality ==="); + test_num = 4; + + tb_mem_1_addr = 16'h0012; + tb_mem_1_valid = 1; + tb_mem_1_rw = 0; + #`CP; + tb_mem_1_valid = 0; + #(10*`CP); + /* ==== Test 3 End ==== */ + + $finish(); + end +endmodule + +`default_nettype wire \ No newline at end of file