Update to top level with interface and test bench
This commit is contained in:
parent
069e52c84b
commit
051f3e68b5
|
@ -93,7 +93,7 @@ endgenerate
|
|||
|
||||
// Control for full and empty, and assigning outputs from the ram
|
||||
always_comb begin
|
||||
i_axi.rdy = ~o_full;
|
||||
i_axi.rdy = ~o_full && ~i_rst;
|
||||
|
||||
o_axi.dat = data_out[0 +: DAT_BITS];
|
||||
o_axi.ctl = data_out[DAT_BITS +: CTL_BITS];
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
module cdc_fifo #(
|
||||
parameter SIZE = 4, // Needs to be a power of 2
|
||||
parameter DAT_BITS = 8,
|
||||
parameter USE_BRAM = 0 // If using BRAM there is an extra cycle delay between reads
|
||||
parameter USE_BRAM = 0, // If using BRAM there is an extra cycle delay between reads
|
||||
parameter RAM_PERFORMANCE = "HIGH_PERFORMANCE"
|
||||
) (
|
||||
input i_clk_a, i_rst_a,
|
||||
input i_clk_b, i_rst_b,
|
||||
|
@ -74,26 +75,41 @@ generate
|
|||
end else begin
|
||||
|
||||
logic [DAT_BITS-1:0] dat_b;
|
||||
logic [1:0] read_cyc;
|
||||
if_ram #(.RAM_WIDTH(DAT_BITS), .RAM_DEPTH(SIZE)) bram_if_rd (i_clk_b, i_rst_b);
|
||||
if_ram #(.RAM_WIDTH(DAT_BITS), .RAM_DEPTH(SIZE)) bram_if_wr (i_clk_a, i_rst_a);
|
||||
|
||||
bram #(
|
||||
.RAM_WIDTH ( DAT_BITS ),
|
||||
.RAM_DEPTH ( SIZE ),
|
||||
.RAM_PERFORMANCE ( "LOW_LATENCY" )
|
||||
.RAM_WIDTH ( DAT_BITS ),
|
||||
.RAM_DEPTH ( SIZE ),
|
||||
.RAM_PERFORMANCE ( RAM_PERFORMANCE )
|
||||
) bram_i (
|
||||
.a ( bram_if_rd ),
|
||||
.b ( bram_if_wr )
|
||||
);
|
||||
|
||||
|
||||
|
||||
always_ff @ (posedge i_clk_b) begin
|
||||
o_val_b <= 0;
|
||||
if (~o_emp_b) o_val_b <= 1;
|
||||
if (o_val_b && i_rdy_b) o_val_b <= 0;
|
||||
if (i_rst_b) begin
|
||||
read_cyc <= 0;
|
||||
o_val_b <= 0;
|
||||
end else begin
|
||||
read_cyc <= read_cyc << 1;
|
||||
o_val_b <= 0;
|
||||
if (~o_emp_b) o_val_b <= 1;
|
||||
|
||||
if (o_val_b && i_rdy_b) begin
|
||||
o_val_b <= 0;
|
||||
read_cyc[0] <= 1;
|
||||
end
|
||||
if (RAM_PERFORMANCE == "HIGH_PERFORMANCE" && read_cyc[0])
|
||||
o_val_b <= 0;
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
|
||||
bram_if_rd.re = 1;
|
||||
bram_if_rd.a = rd_ptr_b[ABITS-1:0];
|
||||
bram_if_rd.d = 0;
|
||||
|
@ -144,7 +160,7 @@ always_comb begin
|
|||
end
|
||||
|
||||
always_comb begin
|
||||
o_rdy_a = ~o_full_a;
|
||||
o_rdy_a = ~o_full_a && ~i_rst_a;
|
||||
o_rd_wrds_b = o_emp_b ? (1 << ABITS) : wr_ptr_b[ABITS-1:0] - rd_ptr_b[ABITS-1:0];
|
||||
end
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
|
||||
module packet_arb # (
|
||||
parameter DAT_BYTS,
|
||||
parameter CTL_BITS,
|
||||
parameter NUM_IN
|
||||
) (
|
||||
input i_clk, i_rst,
|
||||
|
@ -26,10 +28,16 @@ module packet_arb # (
|
|||
if_axi_stream.source o_axi
|
||||
);
|
||||
|
||||
localparam DAT_BITS = DAT_BYTS*8;
|
||||
localparam MOD_BITS = $clog2(DAT_BYTS);
|
||||
|
||||
logic [$clog2(NUM_IN)-1:0] idx;
|
||||
logic locked;
|
||||
|
||||
logic [NUM_IN-1:0] rdy, val, eop;
|
||||
logic [NUM_IN-1:0] rdy, val, eop, sop, err;
|
||||
logic [NUM_IN-1:0][DAT_BITS-1:0] dat;
|
||||
logic [NUM_IN-1:0][MOD_BITS-1:0] mod;
|
||||
logic [NUM_IN-1:0][CTL_BITS-1:0] ctl;
|
||||
|
||||
generate
|
||||
genvar g;
|
||||
|
@ -38,21 +46,28 @@ generate
|
|||
i_axi[g].rdy = rdy[g];
|
||||
val[g] = i_axi[g].val;
|
||||
eop[g] = i_axi[g].eop;
|
||||
sop[g] = i_axi[g].sop;
|
||||
err[g] = i_axi[g].err;
|
||||
dat[g] = i_axi[g].dat;
|
||||
mod[g] = i_axi[g].mod;
|
||||
ctl[g] = i_axi[g].ctl;
|
||||
end
|
||||
|
||||
always_ff @ (posedge i_clk) begin
|
||||
if(g == idx)
|
||||
o_axi.copy_if(i_axi[g].to_struct());
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
always_comb begin
|
||||
rdy = 0;
|
||||
rdy[idx] = o_axi.rdy;
|
||||
o_axi.dat = dat[idx];
|
||||
o_axi.mod = mod[idx];
|
||||
o_axi.ctl = ctl[idx];
|
||||
o_axi.val = val[idx];
|
||||
o_axi.err = err[idx];
|
||||
o_axi.sop = sop[idx];
|
||||
o_axi.eop = eop[idx];
|
||||
end
|
||||
|
||||
// Logic to arbitrate is registered
|
||||
always_ff @ (posedge i_clk) begin
|
||||
if (i_rst) begin
|
||||
locked <= 0;
|
||||
|
|
|
@ -82,7 +82,7 @@ fpga_state_t fpga_state;
|
|||
always_comb begin
|
||||
fpga_state = 0;
|
||||
fpga_state.error = 0;
|
||||
fpga_state.typ1_state = TYP1_IDLE;
|
||||
fpga_state.typ1_state = typ1_msg_state;
|
||||
header = rx_int_if.dat;
|
||||
header0 = rx_typ0_if.dat;
|
||||
header1 = rx_typ1_if.dat;
|
||||
|
@ -199,10 +199,9 @@ always_ff @ (posedge i_clk_core) begin
|
|||
equihash_index_val <= 0;
|
||||
sop_l <= 0;
|
||||
end else begin
|
||||
rx_typ1_if.rdy <= 1;
|
||||
case (typ1_msg_state)
|
||||
|
||||
TYP1_IDLE: begin
|
||||
rx_typ1_if_rdy <= 1;
|
||||
verify_equihash_rpl_val <= 0;
|
||||
equihash_index_val <= 0;
|
||||
sop_l <= 0;
|
||||
|
@ -342,7 +341,7 @@ width_change_cdc_fifo #(
|
|||
.IN_DAT_BYTS ( IN_DAT_BYTS ),
|
||||
.OUT_DAT_BYTS ( CORE_DAT_BYTS ),
|
||||
.CTL_BITS ( 8 ),
|
||||
.FIFO_ABITS ( $clog2(16*1024/IN_DAT_BITS) ),
|
||||
.FIFO_ABITS ( $clog2(1024/IN_DAT_BITS) ),
|
||||
.USE_BRAM ( 1 )
|
||||
)
|
||||
cdc_fifo_rx (
|
||||
|
@ -356,7 +355,9 @@ cdc_fifo_rx (
|
|||
|
||||
// Arbitrator for sending messages back
|
||||
packet_arb # (
|
||||
.NUM_IN ( 2 )
|
||||
.NUM_IN ( 2 ),
|
||||
.DAT_BYTS ( CORE_DAT_BYTS ),
|
||||
.CTL_BITS ( 8 )
|
||||
)
|
||||
packet_arb_tx (
|
||||
.i_clk ( i_clk_core ),
|
||||
|
@ -371,7 +372,7 @@ width_change_cdc_fifo #(
|
|||
.IN_DAT_BYTS ( CORE_DAT_BYTS ),
|
||||
.OUT_DAT_BYTS ( IN_DAT_BYTS ),
|
||||
.CTL_BITS ( 8 ),
|
||||
.FIFO_ABITS ( $clog2(16*1024/CORE_DAT_BYTS) ),
|
||||
.FIFO_ABITS ( $clog2(1024/CORE_DAT_BYTS) ),
|
||||
.USE_BRAM ( 1 )
|
||||
)
|
||||
cdc_fifo_tx (
|
||||
|
|
|
@ -123,54 +123,66 @@ DUT(
|
|||
);
|
||||
|
||||
// This is a tests the sample block 346 in the block chain with the header to verify the equihash solution
|
||||
// Also send a status request to check it is correct
|
||||
// Also send a reset first and then status request to check it is correct
|
||||
task test_block_346_equihash();
|
||||
begin
|
||||
header_t header;
|
||||
fpga_status_rpl_t fpga_status_rpl;
|
||||
fpga_reset_rpl_t fpga_reset_rpl;
|
||||
verify_equihash_rpl_t verify_equihash_rpl;
|
||||
integer signed get_len1, get_len2;
|
||||
logic [common_pkg::MAX_SIM_BYTS*8-1:0] get_dat1, get_dat2;
|
||||
integer signed get_len1, get_len2, get_len3;
|
||||
logic [common_pkg::MAX_SIM_BYTS*8-1:0] get_dat1, get_dat2, get_dat3;
|
||||
logic fail = 0;
|
||||
$display("Running test_block_346_equihash...");
|
||||
|
||||
header.cmd = FPGA_STATUS;
|
||||
header.len = $bits(header_t)/8;
|
||||
|
||||
fork
|
||||
begin
|
||||
// First send reset
|
||||
header.cmd = RESET_FPGA;
|
||||
header.len = $bits(header_t)/8;
|
||||
tx_if.put_stream(header, $bits(header)/8);
|
||||
// Wait for tx_if.rdy to go low (reset started)
|
||||
while (tx_if.rdy) @(posedge tx_if.i_clk);
|
||||
// Then send data
|
||||
start_346 = 1;
|
||||
while(!done_346) @(posedge clk_if);
|
||||
// Then status request
|
||||
header.cmd = FPGA_STATUS;
|
||||
header.len = $bits(header_t)/8;
|
||||
tx_if.put_stream(header, $bits(header)/8);
|
||||
end
|
||||
begin
|
||||
rx_if.get_stream(get_dat1, get_len1);
|
||||
rx_if.get_stream(get_dat2, get_len2);
|
||||
rx_if.get_stream(get_dat1, get_len1); // reset rpl
|
||||
rx_if.get_stream(get_dat2, get_len2); // status rpl
|
||||
rx_if.get_stream(get_dat3, get_len3); // equihash rpl
|
||||
end
|
||||
join
|
||||
|
||||
verify_equihash_rpl = get_dat2;
|
||||
fpga_status_rpl = get_dat1;
|
||||
fpga_reset_rpl = get_dat1;
|
||||
verify_equihash_rpl = get_dat3;
|
||||
fpga_status_rpl = get_dat2;
|
||||
|
||||
fail |= get_len2 != $bits(verify_equihash_rpl_t)/8;
|
||||
fail |= get_len3 != $bits(verify_equihash_rpl_t)/8;
|
||||
fail |= verify_equihash_rpl.hdr.cmd != VERIFY_EQUIHASH_RPL;
|
||||
fail |= verify_equihash_rpl.hdr.len != $bits(verify_equihash_rpl_t)/8;
|
||||
fail |= verify_equihash_rpl.index != 1;
|
||||
fail |= verify_equihash_rpl.bm != 0;
|
||||
|
||||
assert (~fail) else $fatal(1, "%m %t ERROR: test_block_346_equihash equihash rply was wrong:\n%p", $time, verify_equihash_rpl);
|
||||
|
||||
fail |= get_len1 != $bits(fpga_status_rpl_t)/8;
|
||||
fail |= get_len2 != $bits(fpga_status_rpl_t)/8;
|
||||
fail |= fpga_status_rpl.hdr.cmd != FPGA_STATUS_RPL;
|
||||
fail |= fpga_status_rpl.hdr.len != $bits(fpga_status_rpl_t)/8;
|
||||
fail |= fpga_status_rpl.hdr.len != get_len1;
|
||||
fail |= fpga_status_rpl.hdr.len != get_len2;
|
||||
fail |= fpga_status_rpl.version != FPGA_VERSION;
|
||||
fail |= fpga_status_rpl.build_host != "test";
|
||||
fail |= fpga_status_rpl.build_date != "20180311";
|
||||
fail |= fpga_status_rpl.fpga_state.typ1_state == 1;
|
||||
|
||||
fail |= fpga_status_rpl.fpga_state == 1;
|
||||
assert (~fail) else $fatal(1, "%m %t ERROR: test_block_346_equihash status reply was wrong:\n%p", $time, fpga_status_rpl);
|
||||
|
||||
fail |= get_len1 != $bits(fpga_reset_rpl_t)/8;
|
||||
fail |= fpga_reset_rpl.hdr.cmd != RESET_FPGA_RPL;
|
||||
assert (~fail) else $fatal(1, "%m %t ERROR: test_block_346_equihash reset reply was wrong:\n%p", $time, fpga_reset_rpl);
|
||||
|
||||
$display("test_block_346_equihash PASSED");
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue