add lut memory and tests, still need to sort out pipelining
This commit is contained in:
parent
e55d919098
commit
c1620871cf
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
|
@ -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
|
||||
Loading…
Reference in New Issue