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
|
// Control for full and empty, and assigning outputs from the ram
|
||||||
always_comb begin
|
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.dat = data_out[0 +: DAT_BITS];
|
||||||
o_axi.ctl = data_out[DAT_BITS +: CTL_BITS];
|
o_axi.ctl = data_out[DAT_BITS +: CTL_BITS];
|
||||||
|
|
|
@ -22,7 +22,8 @@
|
||||||
module cdc_fifo #(
|
module cdc_fifo #(
|
||||||
parameter SIZE = 4, // Needs to be a power of 2
|
parameter SIZE = 4, // Needs to be a power of 2
|
||||||
parameter DAT_BITS = 8,
|
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_a, i_rst_a,
|
||||||
input i_clk_b, i_rst_b,
|
input i_clk_b, i_rst_b,
|
||||||
|
@ -74,13 +75,14 @@ generate
|
||||||
end else begin
|
end else begin
|
||||||
|
|
||||||
logic [DAT_BITS-1:0] dat_b;
|
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_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);
|
if_ram #(.RAM_WIDTH(DAT_BITS), .RAM_DEPTH(SIZE)) bram_if_wr (i_clk_a, i_rst_a);
|
||||||
|
|
||||||
bram #(
|
bram #(
|
||||||
.RAM_WIDTH ( DAT_BITS ),
|
.RAM_WIDTH ( DAT_BITS ),
|
||||||
.RAM_DEPTH ( SIZE ),
|
.RAM_DEPTH ( SIZE ),
|
||||||
.RAM_PERFORMANCE ( "LOW_LATENCY" )
|
.RAM_PERFORMANCE ( RAM_PERFORMANCE )
|
||||||
) bram_i (
|
) bram_i (
|
||||||
.a ( bram_if_rd ),
|
.a ( bram_if_rd ),
|
||||||
.b ( bram_if_wr )
|
.b ( bram_if_wr )
|
||||||
|
@ -88,12 +90,26 @@ generate
|
||||||
|
|
||||||
|
|
||||||
always_ff @ (posedge i_clk_b) begin
|
always_ff @ (posedge i_clk_b) begin
|
||||||
|
if (i_rst_b) begin
|
||||||
|
read_cyc <= 0;
|
||||||
|
o_val_b <= 0;
|
||||||
|
end else begin
|
||||||
|
read_cyc <= read_cyc << 1;
|
||||||
o_val_b <= 0;
|
o_val_b <= 0;
|
||||||
if (~o_emp_b) o_val_b <= 1;
|
if (~o_emp_b) o_val_b <= 1;
|
||||||
if (o_val_b && i_rdy_b) o_val_b <= 0;
|
|
||||||
|
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
|
end
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
|
|
||||||
bram_if_rd.re = 1;
|
bram_if_rd.re = 1;
|
||||||
bram_if_rd.a = rd_ptr_b[ABITS-1:0];
|
bram_if_rd.a = rd_ptr_b[ABITS-1:0];
|
||||||
bram_if_rd.d = 0;
|
bram_if_rd.d = 0;
|
||||||
|
@ -144,7 +160,7 @@ always_comb begin
|
||||||
end
|
end
|
||||||
|
|
||||||
always_comb begin
|
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];
|
o_rd_wrds_b = o_emp_b ? (1 << ABITS) : wr_ptr_b[ABITS-1:0] - rd_ptr_b[ABITS-1:0];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module packet_arb # (
|
module packet_arb # (
|
||||||
|
parameter DAT_BYTS,
|
||||||
|
parameter CTL_BITS,
|
||||||
parameter NUM_IN
|
parameter NUM_IN
|
||||||
) (
|
) (
|
||||||
input i_clk, i_rst,
|
input i_clk, i_rst,
|
||||||
|
@ -26,10 +28,16 @@ module packet_arb # (
|
||||||
if_axi_stream.source o_axi
|
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 [$clog2(NUM_IN)-1:0] idx;
|
||||||
logic locked;
|
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
|
generate
|
||||||
genvar g;
|
genvar g;
|
||||||
|
@ -38,21 +46,28 @@ generate
|
||||||
i_axi[g].rdy = rdy[g];
|
i_axi[g].rdy = rdy[g];
|
||||||
val[g] = i_axi[g].val;
|
val[g] = i_axi[g].val;
|
||||||
eop[g] = i_axi[g].eop;
|
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
|
end
|
||||||
|
|
||||||
always_ff @ (posedge i_clk) begin
|
|
||||||
if(g == idx)
|
|
||||||
o_axi.copy_if(i_axi[g].to_struct());
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
rdy = 0;
|
rdy = 0;
|
||||||
rdy[idx] = o_axi.rdy;
|
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
|
end
|
||||||
|
|
||||||
|
// Logic to arbitrate is registered
|
||||||
always_ff @ (posedge i_clk) begin
|
always_ff @ (posedge i_clk) begin
|
||||||
if (i_rst) begin
|
if (i_rst) begin
|
||||||
locked <= 0;
|
locked <= 0;
|
||||||
|
|
|
@ -82,7 +82,7 @@ fpga_state_t fpga_state;
|
||||||
always_comb begin
|
always_comb begin
|
||||||
fpga_state = 0;
|
fpga_state = 0;
|
||||||
fpga_state.error = 0;
|
fpga_state.error = 0;
|
||||||
fpga_state.typ1_state = TYP1_IDLE;
|
fpga_state.typ1_state = typ1_msg_state;
|
||||||
header = rx_int_if.dat;
|
header = rx_int_if.dat;
|
||||||
header0 = rx_typ0_if.dat;
|
header0 = rx_typ0_if.dat;
|
||||||
header1 = rx_typ1_if.dat;
|
header1 = rx_typ1_if.dat;
|
||||||
|
@ -199,10 +199,9 @@ always_ff @ (posedge i_clk_core) begin
|
||||||
equihash_index_val <= 0;
|
equihash_index_val <= 0;
|
||||||
sop_l <= 0;
|
sop_l <= 0;
|
||||||
end else begin
|
end else begin
|
||||||
rx_typ1_if.rdy <= 1;
|
|
||||||
case (typ1_msg_state)
|
case (typ1_msg_state)
|
||||||
|
|
||||||
TYP1_IDLE: begin
|
TYP1_IDLE: begin
|
||||||
|
rx_typ1_if_rdy <= 1;
|
||||||
verify_equihash_rpl_val <= 0;
|
verify_equihash_rpl_val <= 0;
|
||||||
equihash_index_val <= 0;
|
equihash_index_val <= 0;
|
||||||
sop_l <= 0;
|
sop_l <= 0;
|
||||||
|
@ -342,7 +341,7 @@ width_change_cdc_fifo #(
|
||||||
.IN_DAT_BYTS ( IN_DAT_BYTS ),
|
.IN_DAT_BYTS ( IN_DAT_BYTS ),
|
||||||
.OUT_DAT_BYTS ( CORE_DAT_BYTS ),
|
.OUT_DAT_BYTS ( CORE_DAT_BYTS ),
|
||||||
.CTL_BITS ( 8 ),
|
.CTL_BITS ( 8 ),
|
||||||
.FIFO_ABITS ( $clog2(16*1024/IN_DAT_BITS) ),
|
.FIFO_ABITS ( $clog2(1024/IN_DAT_BITS) ),
|
||||||
.USE_BRAM ( 1 )
|
.USE_BRAM ( 1 )
|
||||||
)
|
)
|
||||||
cdc_fifo_rx (
|
cdc_fifo_rx (
|
||||||
|
@ -356,7 +355,9 @@ cdc_fifo_rx (
|
||||||
|
|
||||||
// Arbitrator for sending messages back
|
// Arbitrator for sending messages back
|
||||||
packet_arb # (
|
packet_arb # (
|
||||||
.NUM_IN ( 2 )
|
.NUM_IN ( 2 ),
|
||||||
|
.DAT_BYTS ( CORE_DAT_BYTS ),
|
||||||
|
.CTL_BITS ( 8 )
|
||||||
)
|
)
|
||||||
packet_arb_tx (
|
packet_arb_tx (
|
||||||
.i_clk ( i_clk_core ),
|
.i_clk ( i_clk_core ),
|
||||||
|
@ -371,7 +372,7 @@ width_change_cdc_fifo #(
|
||||||
.IN_DAT_BYTS ( CORE_DAT_BYTS ),
|
.IN_DAT_BYTS ( CORE_DAT_BYTS ),
|
||||||
.OUT_DAT_BYTS ( IN_DAT_BYTS ),
|
.OUT_DAT_BYTS ( IN_DAT_BYTS ),
|
||||||
.CTL_BITS ( 8 ),
|
.CTL_BITS ( 8 ),
|
||||||
.FIFO_ABITS ( $clog2(16*1024/CORE_DAT_BYTS) ),
|
.FIFO_ABITS ( $clog2(1024/CORE_DAT_BYTS) ),
|
||||||
.USE_BRAM ( 1 )
|
.USE_BRAM ( 1 )
|
||||||
)
|
)
|
||||||
cdc_fifo_tx (
|
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
|
// 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();
|
task test_block_346_equihash();
|
||||||
begin
|
begin
|
||||||
header_t header;
|
header_t header;
|
||||||
fpga_status_rpl_t fpga_status_rpl;
|
fpga_status_rpl_t fpga_status_rpl;
|
||||||
|
fpga_reset_rpl_t fpga_reset_rpl;
|
||||||
verify_equihash_rpl_t verify_equihash_rpl;
|
verify_equihash_rpl_t verify_equihash_rpl;
|
||||||
integer signed get_len1, get_len2;
|
integer signed get_len1, get_len2, get_len3;
|
||||||
logic [common_pkg::MAX_SIM_BYTS*8-1:0] get_dat1, get_dat2;
|
logic [common_pkg::MAX_SIM_BYTS*8-1:0] get_dat1, get_dat2, get_dat3;
|
||||||
logic fail = 0;
|
logic fail = 0;
|
||||||
$display("Running test_block_346_equihash...");
|
$display("Running test_block_346_equihash...");
|
||||||
|
|
||||||
header.cmd = FPGA_STATUS;
|
|
||||||
header.len = $bits(header_t)/8;
|
|
||||||
|
|
||||||
fork
|
fork
|
||||||
begin
|
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;
|
start_346 = 1;
|
||||||
while(!done_346) @(posedge clk_if);
|
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);
|
tx_if.put_stream(header, $bits(header)/8);
|
||||||
end
|
end
|
||||||
begin
|
begin
|
||||||
rx_if.get_stream(get_dat1, get_len1);
|
rx_if.get_stream(get_dat1, get_len1); // reset rpl
|
||||||
rx_if.get_stream(get_dat2, get_len2);
|
rx_if.get_stream(get_dat2, get_len2); // status rpl
|
||||||
|
rx_if.get_stream(get_dat3, get_len3); // equihash rpl
|
||||||
end
|
end
|
||||||
join
|
join
|
||||||
|
|
||||||
verify_equihash_rpl = get_dat2;
|
fpga_reset_rpl = get_dat1;
|
||||||
fpga_status_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.cmd != VERIFY_EQUIHASH_RPL;
|
||||||
fail |= verify_equihash_rpl.hdr.len != $bits(verify_equihash_rpl_t)/8;
|
fail |= verify_equihash_rpl.hdr.len != $bits(verify_equihash_rpl_t)/8;
|
||||||
fail |= verify_equihash_rpl.index != 1;
|
fail |= verify_equihash_rpl.index != 1;
|
||||||
fail |= verify_equihash_rpl.bm != 0;
|
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);
|
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.cmd != FPGA_STATUS_RPL;
|
||||||
fail |= fpga_status_rpl.hdr.len != $bits(fpga_status_rpl_t)/8;
|
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.version != FPGA_VERSION;
|
||||||
fail |= fpga_status_rpl.build_host != "test";
|
fail |= fpga_status_rpl.build_host != "test";
|
||||||
fail |= fpga_status_rpl.build_date != "20180311";
|
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);
|
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");
|
$display("test_block_346_equihash PASSED");
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue