add lut memory and tests, still need to sort out pipelining

This commit is contained in:
Fischer Moseley 2023-02-28 17:56:19 -05:00
parent e55d919098
commit c1620871cf
6 changed files with 370 additions and 102 deletions

67
lut_mem.gtkw Normal file
View File

@ -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

View File

@ -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;

64
src/manta/lut_mem.v Normal file
View File

@ -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

View File

@ -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

View File

@ -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;

207
test/lut_mem_tb.sv Normal file
View File

@ -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