Update to control block and test bench

This commit is contained in:
bsdevlin 2019-03-17 10:49:16 -04:00
parent 571bfb2dc0
commit e1705a1d5b
6 changed files with 116 additions and 113 deletions

View File

@ -50,7 +50,6 @@ localparam MAX_BYT_MSG = 256; // Max bytes in a reply message
// and one for everything else. This is so we can process these messages even if we are
// running something else.
if_axi_stream #(.DAT_BYTS(CORE_DAT_BYTS), .CTL_BYTS(1)) rx_int_if (i_clk_core);
if_axi_stream #(.DAT_BYTS(CORE_DAT_BYTS), .CTL_BYTS(1)) rx_int0_if (i_clk_core);
if_axi_stream #(.DAT_BYTS(CORE_DAT_BYTS), .CTL_BYTS(1)) rx_int1_if (i_clk_core);
@ -69,23 +68,23 @@ typedef enum {TYP0_IDLE = 0,
typ0_msg_state_t typ0_msg_state;
enum {TYP1_IDLE = 0,
typedef enum {TYP1_IDLE = 0,
TYP1_VERIFY_EQUIHASH = 1,
TYP1_IGNORE = 2} typ1_msg_state;
TYP1_SEND_IGNORE = 2,
TYP1_IGNORE = 3} typ1_msg_state_t;
typ1_msg_state_t typ1_msg_state;
header_t header, header0, header1, header0_l, header1_l;
//fpga_status_rpl_t fpga_status_rpl;
//fpga_reset_rpl_t fpga_reset_rpl;
//fpga_ignore_rpl_t fpga0_ignore_rpl;
verify_equihash_rpl_t verify_equihash_rpl;
logic verify_equihash_rpl_val;
logic [7:0] reset_cnt;
logic [$clog2(MAX_BYT_MSG) -1:0] typ0_wrd_cnt, typ1_wrd_cnt;
logic [MAX_BYT_MSG*8 -1:0] typ0_msg;
logic [MAX_BYT_MSG*8 -1:0] typ0_msg, typ1_msg;
logic [63:0] equihash_index;
logic equihash_index_val, rx_typ1_if_rdy, verify_equihash_rpl_val;
logic equihash_index_val, rx_typ1_if_rdy;
logic sop_l;
logic eop_typ0_l;
logic eop_typ0_l, eop_typ1_l;
fpga_state_t fpga_state;
always_comb begin
@ -104,9 +103,6 @@ always_ff @ (posedge i_clk_core) begin
typ0_msg_state <= TYP0_IDLE;
header0_l <= 0;
tx_arb_in_if[0].reset_source();
// fpga_status_rpl <= 0;
// fpga_reset_rpl <= 0;
/// fpga0_ignore_rpl <= 0;
typ0_wrd_cnt <= 0;
o_usr_rst <= 0;
reset_cnt <= 0;
@ -117,10 +113,6 @@ always_ff @ (posedge i_clk_core) begin
case (typ0_msg_state)
TYP0_IDLE: begin
//fpga_status_rpl <= get_fpga_status_rpl(BUILD_HOST, BUILD_DATE, fpga_state);
//fpga_reset_rpl <= get_fpga_reset_rpl();
//fpga0_ignore_rpl <= get_fpga_ignore_rpl(header0);
if (rx_typ0_if.val && rx_typ0_if.rdy) begin
header0_l <= header0;
rx_typ0_if.rdy <= 0;
@ -139,6 +131,7 @@ always_ff @ (posedge i_clk_core) begin
end
default: begin
typ0_msg <= get_fpga_ignore_rpl(header0);
typ0_wrd_cnt <= $bits(fpga_ignore_rpl_t)/8;
eop_typ0_l <= rx_typ0_if.eop;
typ0_msg_state <= TYP0_SEND_IGNORE;
end
@ -146,23 +139,7 @@ always_ff @ (posedge i_clk_core) begin
end
end
TYP0_SEND_STATUS: begin
/*
rx_typ0_if.rdy <= 0;
if (~tx_arb_in_if[0].val || (tx_arb_in_if[0].rdy && tx_arb_in_if[0].val)) begin
tx_arb_in_if[0].dat <= fpga_status_rpl;
tx_arb_in_if[0].val <= 1;
tx_arb_in_if[0].sop <= typ0_wrd_cnt == $bits(fpga_status_rpl_t)/8;
tx_arb_in_if[0].eop <= typ0_wrd_cnt <= CORE_DAT_BYTS;
tx_arb_in_if[0].mod <= typ0_wrd_cnt < CORE_DAT_BYTS ? typ0_wrd_cnt : 0;
typ0_wrd_cnt <= (typ0_wrd_cnt > CORE_DAT_BYTS) ? (typ0_wrd_cnt - CORE_DAT_BYTS) : 0;
fpga_status_rpl <= fpga_status_rpl >> CORE_DAT_BITS;
if (typ0_wrd_cnt == 0) begin
tx_arb_in_if[0].val <= 0;
typ0_msg_state <= TYP0_IDLE;
end
end
*/
send_typ0_message($bits(fpga_status_rpl_t)/8, typ0_msg, typ0_wrd_cnt);
send_typ0_message($bits(fpga_status_rpl_t)/8);
end
TYP0_RESET_FPGA: begin
rx_typ0_if.rdy <= 0;
@ -172,40 +149,11 @@ always_ff @ (posedge i_clk_core) begin
reset_cnt <= reset_cnt - 1;
if (~o_usr_rst) begin
send_typ0_message($bits(fpga_reset_rpl_t)/8, typ0_msg, typ0_wrd_cnt);
/*
if (~tx_arb_in_if[0].val || (tx_arb_in_if[0].rdy && tx_arb_in_if[0].val)) begin
tx_arb_in_if[0].dat <= fpga_reset_rpl;
tx_arb_in_if[0].val <= 1;
tx_arb_in_if[0].sop <= typ0_wrd_cnt == $bits(fpga_reset_rpl_t)/8;
tx_arb_in_if[0].eop <= typ0_wrd_cnt <= CORE_DAT_BYTS;
tx_arb_in_if[0].mod <= typ0_wrd_cnt < CORE_DAT_BYTS ? typ0_wrd_cnt : 0;
typ0_wrd_cnt <= (typ0_wrd_cnt > CORE_DAT_BYTS) ? (typ0_wrd_cnt - CORE_DAT_BYTS) : 0;
fpga_reset_rpl <= fpga_reset_rpl >> CORE_DAT_BITS;
if (typ0_wrd_cnt == 0) begin
tx_arb_in_if[0].val <= 0;
typ0_msg_state <= TYP0_IDLE;
end
end*/
send_typ0_message($bits(fpga_reset_rpl_t)/8);
end
end
TYP0_SEND_IGNORE: begin
send_typ0_message($bits(fpga0_ignore_rpl_t)/8, typ0_msg, typ0_wrd_cnt, eop_typ0_l ? TYP0_IDLE :TYP0_IGNORE);
/*
rx_typ0_if.rdy <= 0;
if (~tx_arb_in_if[0].val || (tx_arb_in_if[0].rdy && tx_arb_in_if[0].val)) begin
tx_arb_in_if[0].dat <= fpga_ignore_rpl;
tx_arb_in_if[0].val <= 1;
tx_arb_in_if[0].sop <= typ0_wrd_cnt == $bits(fpga0_ignore_rpl_t)/8;
tx_arb_in_if[0].eop <= typ0_wrd_cnt <= CORE_DAT_BYTS;
tx_arb_in_if[0].mod <= typ0_wrd_cnt < CORE_DAT_BYTS ? typ0_wrd_cnt : 0;
typ0_wrd_cnt <= (typ0_wrd_cnt > CORE_DAT_BYTS) ? (typ0_wrd_cnt - CORE_DAT_BYTS) : 0;
fpga_ignore_rpl <= fpga_ignore_rpl >> CORE_DAT_BITS;
if (typ0_wrd_cnt == 0) begin
tx_arb_in_if[0].val <= 0;
typ0_msg_state <= eop_typ0_l ? TYP0_IDLE :TYP0_IGNORE;
end
end*/
send_typ0_message($bits(fpga_ignore_rpl_t)/8, eop_typ0_l ? TYP0_IDLE : TYP0_IGNORE);
end
TYP0_IGNORE: begin
rx_typ0_if.rdy <= 1;
@ -217,17 +165,18 @@ always_ff @ (posedge i_clk_core) begin
end
// Task to help build reply messages. Assume no message will be more than MAX_BYT_MSG bytes
task automatic send_typ0_message(input logic [$clog2(MAX_BYT_MSG)-1:0] msg_size, ref logic [MAX_BYT_MSG*8-1:0] msg, ref logic [$clog2(MAX_BYT_MSG)-1:0] byt_cnt, input typ0_msg_state_t nxt_state = TYP0_IDLE);
task send_typ0_message(input logic [$clog2(MAX_BYT_MSG)-1:0] msg_size,
input typ0_msg_state_t nxt_state = TYP0_IDLE);
rx_typ0_if.rdy <= 0;
if (~tx_arb_in_if[0].val || (tx_arb_in_if[0].rdy && tx_arb_in_if[0].val)) begin
tx_arb_in_if[0].dat <= msg;
tx_arb_in_if[0].dat <= typ0_msg;
tx_arb_in_if[0].val <= 1;
tx_arb_in_if[0].sop <= byt_cnt == msg_size;
tx_arb_in_if[0].eop <= byt_cnt <= CORE_DAT_BYTS;
tx_arb_in_if[0].mod <= byt_cnt < CORE_DAT_BYTS ? byt_cnt : 0;
byt_cnt <= (byt_cnt > CORE_DAT_BYTS) ? (byt_cnt - CORE_DAT_BYTS) : 0;
msg <= msg >> CORE_DAT_BITS;
if (byt_cnt == 0) begin
tx_arb_in_if[0].sop <= typ0_wrd_cnt == msg_size;
tx_arb_in_if[0].eop <= typ0_wrd_cnt <= CORE_DAT_BYTS;
tx_arb_in_if[0].mod <= typ0_wrd_cnt < CORE_DAT_BYTS ? typ0_wrd_cnt : 0;
typ0_wrd_cnt <= (typ0_wrd_cnt > CORE_DAT_BYTS) ? (typ0_wrd_cnt - CORE_DAT_BYTS) : 0;
typ0_msg <= typ0_msg >> CORE_DAT_BITS;
if (typ0_wrd_cnt == 0) begin
tx_arb_in_if[0].val <= 0;
typ0_msg_state <= nxt_state;
end
@ -249,12 +198,13 @@ always_ff @ (posedge i_clk_core) begin
header1_l <= 0;
tx_arb_in_if[1].reset_source();
o_equihash_axi.reset_source();
verify_equihash_rpl <= 0;
typ1_wrd_cnt <= 0;
equihash_index <= 0;
verify_equihash_rpl_val <= 0;
equihash_index_val <= 0;
sop_l <= 0;
eop_typ1_l <= 0;
typ1_msg <= 0;
end else begin
// TODO add IGNORE type here
case (typ1_msg_state)
@ -272,9 +222,12 @@ always_ff @ (posedge i_clk_core) begin
typ1_wrd_cnt <= $bits(verify_equihash_rpl_t)/8;
typ1_msg_state <= TYP1_VERIFY_EQUIHASH;
end
default:
if (~rx_typ1_if.eop)
typ1_msg_state <= TYP1_IGNORE;
default: begin
typ1_msg <= get_fpga_ignore_rpl(header1);
typ1_wrd_cnt <= $bits(fpga_ignore_rpl_t)/8;
eop_typ1_l <= rx_typ1_if.eop;
typ1_msg_state <= TYP1_SEND_IGNORE;
end
endcase
end
end
@ -302,26 +255,17 @@ always_ff @ (posedge i_clk_core) begin
// Wait for reply with result
if (i_equihash_mask_val && ~verify_equihash_rpl_val) begin
verify_equihash_rpl <= get_verify_equihash_rpl(i_equihash_mask, equihash_index);
typ1_msg <= get_verify_equihash_rpl(i_equihash_mask, equihash_index);
verify_equihash_rpl_val <= 1;
end
// Send result
if (verify_equihash_rpl_val) begin
if (~tx_arb_in_if[1].val || (tx_arb_in_if[1].rdy && tx_arb_in_if[1].val)) begin
tx_arb_in_if[1].dat <= verify_equihash_rpl;
tx_arb_in_if[1].val <= 1;
tx_arb_in_if[1].sop <= typ1_wrd_cnt == $bits(verify_equihash_rpl_t)/8;
tx_arb_in_if[1].eop <= typ1_wrd_cnt <= CORE_DAT_BYTS;
tx_arb_in_if[1].mod <= typ1_wrd_cnt < CORE_DAT_BYTS ? typ1_wrd_cnt : 0;
typ1_wrd_cnt <= (typ1_wrd_cnt > CORE_DAT_BYTS) ? (typ1_wrd_cnt - CORE_DAT_BYTS) : 0;
verify_equihash_rpl <= verify_equihash_rpl >> CORE_DAT_BITS;
if (typ1_wrd_cnt == 0) begin
tx_arb_in_if[1].val <= 0;
typ1_msg_state <= TYP1_IDLE;
end
send_typ1_message($bits(verify_equihash_rpl_t)/8);
end
end
TYP1_SEND_IGNORE: begin
send_typ1_message($bits(fpga_ignore_rpl_t)/8, eop_typ1_l ? TYP1_IDLE : TYP1_IGNORE);
end
TYP1_IGNORE: begin
rx_typ1_if_rdy <= 1;
@ -332,6 +276,25 @@ always_ff @ (posedge i_clk_core) begin
end
end
// Task to help build reply messages. Assume no message will be more than MAX_BYT_MSG bytes
task send_typ1_message(input logic [$clog2(MAX_BYT_MSG)-1:0] msg_size,
input typ1_msg_state_t nxt_state = TYP1_IDLE);
rx_typ1_if.rdy <= 0;
if (~tx_arb_in_if[1].val || (tx_arb_in_if[1].rdy && tx_arb_in_if[1].val)) begin
tx_arb_in_if[1].dat <= typ1_msg;
tx_arb_in_if[1].val <= 1;
tx_arb_in_if[1].sop <= typ1_wrd_cnt == msg_size;
tx_arb_in_if[1].eop <= typ1_wrd_cnt <= CORE_DAT_BYTS;
tx_arb_in_if[1].mod <= typ1_wrd_cnt < CORE_DAT_BYTS ? typ1_wrd_cnt : 0;
typ1_wrd_cnt <= (typ1_wrd_cnt > CORE_DAT_BYTS) ? (typ1_wrd_cnt - CORE_DAT_BYTS) : 0;
typ1_msg <= typ1_msg >> CORE_DAT_BITS;
if (typ1_wrd_cnt == 0) begin
tx_arb_in_if[1].val <= 0;
typ1_msg_state <= nxt_state;
end
end
endtask
// Logic to mux the packet depending on its command type
logic msg_type, msg_type_l;
always_comb begin

View File

@ -35,7 +35,8 @@ module secp256k1_mod (
// output
output logic [255:0] o_dat,
input i_rdy,
output logic o_val
output logic o_val,
output logic o_err // Will go high if after 1 reduction we are still >= p
);
import secp256k1_pkg::*;
@ -55,9 +56,11 @@ always_ff @ (posedge i_clk) begin
state <= IDLE;
o_val <= 0;
o_rdy <= 0;
o_err <= 0;
end else begin
o_rdy <= 0;
o_dat <= a_ >= p_eq ? (a_ - p_eq) : a_;
case(state)
IDLE: begin
o_rdy <= 1;
@ -76,10 +79,12 @@ always_ff @ (posedge i_clk) begin
end
S2: begin
o_val <= 1;
o_err <= a_ >= 2* p_eq;
if (o_val && i_rdy) begin
state <=IDLE;
o_rdy <= 1;
o_val <= 0;
o_err <= 0;
end
end
endcase

View File

@ -95,6 +95,7 @@ package zcash_fpga_pkg;
function fpga_ignore_rpl_t get_fpga_ignore_rpl(header_t hdr);
get_fpga_ignore_rpl.hdr = '{cmd:FPGA_IGNORE_RPL, len:$bits(fpga_ignore_rpl_t)/8};
get_fpga_ignore_rpl.ignore_hdr = hdr;
endfunction
function fpga_status_rpl_t get_fpga_status_rpl(input [63:0] build_host, build_date, fpga_state_t fpga_state);

View File

@ -38,8 +38,6 @@ module zcash_fpga_top
logic rst_core0, rst_core1, rst_if, usr_rst, usr_rst_r;
logic rst_200, rst_300;
if_axi_stream #(.DAT_BYTS(CORE_DAT_BYTS)) equihash_axi(i_clk_core0);
equihash_bm_t equihash_mask;
@ -101,7 +99,7 @@ equihash_verif_top #(
)
equihash_verif_top (
.i_clk ( i_clk_core0 ),
.i_rst ( core_rst ),
.i_rst ( rst_core0 ),
.i_clk_300 ( i_clk_core1 ), // Faster clock
.i_rst_300 ( rst_core1 ),
.i_axi ( equihash_axi ),

View File

@ -40,11 +40,15 @@ end
always_comb begin
out_if.sop = 1;
out_if.eop = 1;
out_if.err = 0;
out_if.ctl = 0;
out_if.mod = 0;
end
// Check for errors
always_ff @ (posedge clk)
if (out_if.val && out_if.err)
$error(1, "%m %t ERROR: output .err asserted", $time);
secp256k1_mod secp256k1_mod
(
.i_clk( clk ),
@ -53,6 +57,7 @@ secp256k1_mod secp256k1_mod
.i_val( in_if.val ),
.o_rdy( in_if.rdy ),
.o_dat( out_if.dat ),
.o_err( out_if.err ),
.i_rdy( out_if.rdy ),
.o_val( out_if.val )
);
@ -77,18 +82,18 @@ endtask;
task test_loop();
begin
integer signed get_len, i, max;
logic [common_pkg::MAX_SIM_BYTS*8-1:0] expected, in_dat, get_dat;
logic [common_pkg::MAX_SIM_BYTS*8-1:0] in_dat, get_dat;
logic [256:0] expected;
$display("Running test_loop...");
in_dat = 1 << 433;
expected = 256'd822752465816620949324161418291805943222876982255305228346720256;
i = 0;
max = 10000;
repeat (max) begin
max = 1000;
while (i < max) begin
in_dat = in_dat*2;
expected = expected*2;
while (expected >= p_eq)
expected = expected - p_eq;
in_dat = random_vector(512);
in_dat = in_dat % (p_eq*p_eq);
expected = in_dat % p_eq;
fork
in_if.put_stream(in_dat, 512/8);
@ -109,8 +114,10 @@ initial begin
out_if.rdy = 0;
in_if.val = 0;
#(40*CLK_PERIOD);
test0();
test_loop();
test_loop(); // This one is a bit slower since we compute the expected result
#1us $finish();
end
endmodule

View File

@ -112,10 +112,10 @@ zcash_fpga_top #(
)
DUT(
// Clocks and resets
.i_clk_200 ( clk_200 ),
.i_rst_200 ( rst_200 ),
.i_clk_300 ( clk_300 ),
.i_rst_300 ( rst_300 ),
.i_clk_core0 ( clk_200 ),
.i_rst_core0 ( rst_200 ),
.i_clk_core1 ( clk_300 ),
.i_rst_core1 ( rst_300 ),
.i_clk_if ( clk_if ),
.i_rst_if ( rst_if ),
.rx_if ( tx_if ),
@ -188,14 +188,43 @@ begin
end
endtask
// This task sends a malformed message and checks it gets ignored
task test_ignored_message();
begin
header_t header;
fpga_ignore_rpl_t fpga_ignore_rpl;
integer signed get_len;
logic [common_pkg::MAX_SIM_BYTS*8-1:0] get_dat;
logic fail = 0;
$display("Running test_ignored_message...");
// Some header value that is invalid
header = {$bits(header_t){1'b1}};
header.cmd[8 +: 8] = 0;
fork
tx_if.put_stream(header, $bits(header)/8);
rx_if.get_stream(get_dat, get_len);
join
fpga_ignore_rpl = get_dat;
fail |= get_len != $bits(fpga_ignore_rpl_t)/8;
fail |= fpga_ignore_rpl.hdr.cmd != FPGA_IGNORE_RPL;
fail |= fpga_ignore_rpl.hdr.len != $bits(fpga_ignore_rpl_t)/8;
assert (~fail) else $fatal(1, "%m %t ERROR: test_ignored_message rply was wrong:\n%p", $time, fpga_ignore_rpl);
$display("test_ignored_message PASSED");
end
endtask
// Main testbench calls
initial begin
rx_if.rdy = 0;
#20us; // Let internal memories reset
test_block_346_equihash();
test_ignored_message();
test_block_346_equihash();
#1us $finish();