126 lines
2.3 KiB
Coq
126 lines
2.3 KiB
Coq
|
`include "heron_states.v"
|
||
|
|
||
|
module heron_top_tb();
|
||
|
`define ASSERT(c, msg) if (!c) begin $display("%c[31mAssertion Failed: %s%c[0m", 27, msg, 27); $finish(2); end
|
||
|
`define ASSERT_STATE(state) `ASSERT((fsm_state == state), "not expected state")
|
||
|
|
||
|
parameter CYCLE = 50;
|
||
|
|
||
|
wire [31:0] edb;
|
||
|
wire [31:0] eab;
|
||
|
wire ready;
|
||
|
wire ram_wr_en, ram_rd_en;
|
||
|
wire [3:0] fsm_state;
|
||
|
assign fsm_state = heron.fsm.state;
|
||
|
|
||
|
reg reset;
|
||
|
reg load = 0;
|
||
|
reg [15:0] i;
|
||
|
|
||
|
reg clk = 1'b0;
|
||
|
always #(CYCLE/2) clk = ~clk;
|
||
|
|
||
|
reg [31:0] ram [0:1023];
|
||
|
|
||
|
wire ram0;
|
||
|
wire ram1;
|
||
|
wire ram2;
|
||
|
assign ram0 = ram[0];
|
||
|
assign ram1 = ram[1];
|
||
|
assign ram2 = ram[2];
|
||
|
|
||
|
assign edb = ram_rd_en ? ram[eab[9:0]] : 32'bz;
|
||
|
|
||
|
always @ (posedge clk) begin
|
||
|
if (ram_wr_en) begin
|
||
|
ram[eab[9:0]] <= edb;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
heron_top heron(
|
||
|
.clk(clk),
|
||
|
.load(load),
|
||
|
.reset(reset),
|
||
|
.edb(edb),
|
||
|
.eab(eab),
|
||
|
.ram_rd_en(ram_rd_en),
|
||
|
.ram_wr_en(ram_wr_en),
|
||
|
.ready(ready)
|
||
|
);
|
||
|
|
||
|
initial begin
|
||
|
$dumpfile("heron_top_tb.vcd");
|
||
|
$dumpvars;
|
||
|
|
||
|
ram[0] = 3;
|
||
|
ram[3] = 4;
|
||
|
|
||
|
ram[2] = 0;
|
||
|
ram[1] = 1;
|
||
|
end
|
||
|
|
||
|
initial begin
|
||
|
`ASSERT_STATE(`IDLE)
|
||
|
#(5*CYCLE)
|
||
|
load = 1;
|
||
|
#(CYCLE)
|
||
|
load = 0;
|
||
|
// load mem[0] -> number of operands
|
||
|
`ASSERT_STATE(`LD_N_1)
|
||
|
#(CYCLE)
|
||
|
// load...
|
||
|
`ASSERT_STATE(`LD_N_2)
|
||
|
#(CYCLE)
|
||
|
// if (mem[0] > 0) then
|
||
|
`ASSERT_STATE(`I_GT_ZERO)
|
||
|
#(CYCLE)
|
||
|
// load mem[1]...
|
||
|
`ASSERT_STATE(`LD_S_1)
|
||
|
#(CYCLE)
|
||
|
// ...load
|
||
|
`ASSERT_STATE(`LD_S_2)
|
||
|
#(CYCLE)
|
||
|
// if (mem[1] > 1) then
|
||
|
`ASSERT_STATE(`S_GT_ONE)
|
||
|
#(CYCLE)
|
||
|
// x_0 = s / 2
|
||
|
`ASSERT_STATE(`X_1)
|
||
|
#(CYCLE)
|
||
|
// s / x_n...
|
||
|
`ASSERT_STATE(`DIV_2)
|
||
|
#(CYCLE)
|
||
|
// ..divide
|
||
|
`ASSERT_STATE(`DIV_3)
|
||
|
#(CYCLE)
|
||
|
// x_1 = x_n + (s / x_n) / 2
|
||
|
`ASSERT_STATE(`DIV_4)
|
||
|
#(CYCLE)
|
||
|
// if (old_x <= x_1) ...
|
||
|
`ASSERT_STATE(`OLD_X_LTE_X_1)
|
||
|
#(CYCLE)
|
||
|
// ... then
|
||
|
`ASSERT_STATE(`OLD_X_LTE_X_2)
|
||
|
#(CYCLE)
|
||
|
// store mem[1] = 2
|
||
|
`ASSERT_STATE(`STORE_X)
|
||
|
#(CYCLE)
|
||
|
// i--
|
||
|
`ASSERT(ram[3] == 2, "sqrt(4) == 2")
|
||
|
`ASSERT(ram[3] == 1, "sqrt(4) == 2")
|
||
|
`ASSERT_STATE(`DEC_I)
|
||
|
#(CYCLE)
|
||
|
// if (i > 0) then ...
|
||
|
`ASSERT_STATE(`I_GT_ZERO)
|
||
|
|
||
|
for (i = 0; i < 1000; i = i + 1) begin
|
||
|
if (ready != 0) begin
|
||
|
$display("%c[32mSUCCESS: heron_top_tb tests bench finished;%c[0m", 27, 27);
|
||
|
$finish;
|
||
|
end
|
||
|
#(CYCLE) ;
|
||
|
end
|
||
|
$display("%c[31mFAILED: heron_top_tb tests timeout!%c[0m", 27, 27);
|
||
|
$finish(1);
|
||
|
end
|
||
|
endmodule
|