add cadence verilog code
This commit is contained in:
parent
c72c930bc0
commit
f1d6e026c8
12
cadence/heron_comma_fix/functional/verilog.v
Normal file
12
cadence/heron_comma_fix/functional/verilog.v
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
module heron_comma_fix (A,Y);
|
||||||
|
parameter comma = 8;
|
||||||
|
parameter comma_fix = comma / 2;
|
||||||
|
|
||||||
|
|
||||||
|
input [31:0] A;
|
||||||
|
output [31:0] Y;
|
||||||
|
wire [31:0] Y;
|
||||||
|
|
||||||
|
assign Y[(31 - comma_fix):0] = A[(31 - comma_fix):0];
|
||||||
|
assign Y[31:(31 - comma_fix)] = 0;
|
||||||
|
endmodule
|
113
cadence/heron_ctrl/functional/verilog.v
Normal file
113
cadence/heron_ctrl/functional/verilog.v
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
`include "heron_states.v"
|
||||||
|
|
||||||
|
module heron_ctrl(
|
||||||
|
ctrl_bus,
|
||||||
|
// rest
|
||||||
|
state,
|
||||||
|
ready,
|
||||||
|
ram_rd_en,
|
||||||
|
ram_wr_en);
|
||||||
|
|
||||||
|
// readability
|
||||||
|
parameter ON = 1'b1;
|
||||||
|
parameter OFF = 1'b0;
|
||||||
|
parameter MINUS = 1'b1;
|
||||||
|
|
||||||
|
input [3:0] state;
|
||||||
|
output ready;
|
||||||
|
output ram_rd_en, ram_wr_en;
|
||||||
|
|
||||||
|
output [22:0] ctrl_bus;
|
||||||
|
`define CTRL_WIRE(name,port) \
|
||||||
|
reg name; \
|
||||||
|
assign ctrl_bus[port] = name;
|
||||||
|
`include "heron_ctrl_wires.v"
|
||||||
|
`undef CTRL_WIRE
|
||||||
|
|
||||||
|
reg ready = OFF;
|
||||||
|
reg ram_rd_en = OFF;
|
||||||
|
reg ram_wr_en = OFF;
|
||||||
|
|
||||||
|
always @(state) begin
|
||||||
|
ready = OFF;
|
||||||
|
ram_rd_en = OFF;
|
||||||
|
ram_wr_en = OFF;
|
||||||
|
|
||||||
|
`define CTRL_WIRE(name,port) name = OFF;
|
||||||
|
`include "heron_ctrl_wires.v"
|
||||||
|
`undef CTRL_WIRE
|
||||||
|
|
||||||
|
case (state)
|
||||||
|
`IDLE: begin
|
||||||
|
ready = ON;
|
||||||
|
end
|
||||||
|
`LD_N_1: begin
|
||||||
|
k0_to_a = ON;
|
||||||
|
a_to_eab = ON;
|
||||||
|
edb_to_din = ON;
|
||||||
|
ram_rd_en = ON;
|
||||||
|
end
|
||||||
|
`LD_N_2: begin
|
||||||
|
din_to_a = ON;
|
||||||
|
k0_to_b = ON;
|
||||||
|
alu_set_z = ON;
|
||||||
|
end
|
||||||
|
`I_GT_ZERO: begin
|
||||||
|
alu_res_to_a = ON;
|
||||||
|
a_to_i = ON;
|
||||||
|
end
|
||||||
|
`LD_S_1: begin
|
||||||
|
i_to_a = ON;
|
||||||
|
edb_to_din = ON;
|
||||||
|
a_to_eab = ON;
|
||||||
|
ram_rd_en = ON;
|
||||||
|
end
|
||||||
|
`LD_S_2: begin
|
||||||
|
din_to_a = ON;
|
||||||
|
a_to_s = ON;
|
||||||
|
k1_to_b = ON;
|
||||||
|
alu_mode = MINUS;
|
||||||
|
alu_set_s = ON;
|
||||||
|
alu_set_z = ON;
|
||||||
|
end
|
||||||
|
`S_GT_ONE:; // noop
|
||||||
|
`X_1: begin
|
||||||
|
s_to_a_shift_1 = ON;
|
||||||
|
s_to_b = ON;
|
||||||
|
|
||||||
|
a_to_old_x = ON;
|
||||||
|
a_to_x = ON;
|
||||||
|
end
|
||||||
|
`DIV_1: begin
|
||||||
|
x_to_a = ON;
|
||||||
|
s_to_b = ON;
|
||||||
|
end
|
||||||
|
`DIV_2:; // noop
|
||||||
|
`DIV_3:; // noop
|
||||||
|
`DIV_4: begin
|
||||||
|
x_to_a = ON;
|
||||||
|
div_to_b_shift_1 = ON;
|
||||||
|
end
|
||||||
|
`OLD_X_LTE_X_1: begin
|
||||||
|
alu_res_to_a = ON;
|
||||||
|
a_to_x = ON;
|
||||||
|
old_x_to_b = ON;
|
||||||
|
alu_set_c = ON;
|
||||||
|
end
|
||||||
|
`OLD_X_LTE_X_2: begin
|
||||||
|
x_to_a = ON;
|
||||||
|
a_to_old_x = ON;
|
||||||
|
end
|
||||||
|
`STORE_X: begin
|
||||||
|
x_to_b_shifted = ON;
|
||||||
|
ram_wr_en = ON;
|
||||||
|
end
|
||||||
|
`DEC_I: begin
|
||||||
|
i_to_a = ON;
|
||||||
|
k1_to_b = ON;
|
||||||
|
alu_mode = MINUS;
|
||||||
|
alu_set_z = ON;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
endmodule
|
25
cadence/heron_ctrl_tb/functional/verilog.v
Normal file
25
cadence/heron_ctrl_tb/functional/verilog.v
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
module heron_fsm_tb;
|
||||||
|
task assert;
|
||||||
|
input condition;
|
||||||
|
input [(20*8 - 1):0] message;
|
||||||
|
begin
|
||||||
|
if (condition !== 1'b1)
|
||||||
|
begin
|
||||||
|
$display("Assertion Failed: %s", message);
|
||||||
|
$finish(2);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
reg[3:0] state;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$dumpfile("ctrl.vcd");
|
||||||
|
$dumpvars;
|
||||||
|
end
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("Control logic tests passed!");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
end
|
33
cadence/heron_ctrl_wires/functional/verilog.v
Normal file
33
cadence/heron_ctrl_wires/functional/verilog.v
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
module heron_ctrl_wires (
|
||||||
|
ctrl_bus,
|
||||||
|
a_to_eab,
|
||||||
|
a_to_i,
|
||||||
|
a_to_old_x,
|
||||||
|
a_to_s,
|
||||||
|
a_to_x,
|
||||||
|
alu_mode,
|
||||||
|
alu_res_to_a,
|
||||||
|
alu_set_c,
|
||||||
|
alu_set_s,
|
||||||
|
alu_set_z,
|
||||||
|
din_to_a,
|
||||||
|
div_to_b_shift_1,
|
||||||
|
edb_to_din,
|
||||||
|
i_to_a,
|
||||||
|
k0_to_a,
|
||||||
|
k0_to_b,
|
||||||
|
k1_to_b,
|
||||||
|
old_x_to_b,
|
||||||
|
s_to_a_shift_1,
|
||||||
|
s_to_b,
|
||||||
|
x_to_a,
|
||||||
|
x_to_b_shifted
|
||||||
|
);
|
||||||
|
|
||||||
|
input [22:0] ctrl_bus;
|
||||||
|
`define CTRL_WIRE(name,port) \
|
||||||
|
output name; \
|
||||||
|
assign name = ctrl_bus[port];
|
||||||
|
`include "heron_ctrl_wires.v"
|
||||||
|
`undef CTRL_WIRE
|
||||||
|
endmodule
|
68
cadence/heron_fsm/functional/verilog.v
Normal file
68
cadence/heron_fsm/functional/verilog.v
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
`include "heron_states.v"
|
||||||
|
|
||||||
|
module heron_fsm(clk, load, reset, flag_z, flag_c, flag_s, state);
|
||||||
|
input clk;
|
||||||
|
input load;
|
||||||
|
input reset;
|
||||||
|
|
||||||
|
input flag_z;
|
||||||
|
input flag_c;
|
||||||
|
input flag_s;
|
||||||
|
|
||||||
|
output [3:0] state;
|
||||||
|
|
||||||
|
reg [3:0] state = `IDLE;
|
||||||
|
reg [3:0] next_state = `IDLE;
|
||||||
|
|
||||||
|
always @(posedge clk or posedge reset)
|
||||||
|
if(reset) begin
|
||||||
|
state <= `IDLE;
|
||||||
|
end else begin
|
||||||
|
state <= next_state;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(state or flag_z or load)
|
||||||
|
case(state)
|
||||||
|
`IDLE: begin
|
||||||
|
if(load) begin
|
||||||
|
next_state = `LD_N_1;
|
||||||
|
end else begin
|
||||||
|
next_state = `IDLE;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
`LD_N_1: next_state = `LD_N_2;
|
||||||
|
`LD_N_2: next_state = `I_GT_ZERO;
|
||||||
|
`I_GT_ZERO: begin
|
||||||
|
if (flag_z) begin
|
||||||
|
next_state = `IDLE;
|
||||||
|
end else begin
|
||||||
|
next_state = `LD_S_1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
`LD_S_1: next_state = `LD_S_2;
|
||||||
|
`LD_S_2: next_state = `S_GT_ONE;
|
||||||
|
`S_GT_ONE: begin
|
||||||
|
if (flag_s || flag_z) begin
|
||||||
|
next_state = `STORE_X;
|
||||||
|
end else begin
|
||||||
|
next_state = `X_1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
`X_1: next_state = `DIV_2;
|
||||||
|
`DIV_1: next_state = `DIV_2;
|
||||||
|
`DIV_2: next_state = `DIV_3;
|
||||||
|
`DIV_3: next_state = `DIV_4;
|
||||||
|
`DIV_4: next_state = `OLD_X_LTE_X_1;
|
||||||
|
`OLD_X_LTE_X_1: next_state = `OLD_X_LTE_X_2;
|
||||||
|
`OLD_X_LTE_X_2: begin
|
||||||
|
if (flag_c) begin
|
||||||
|
next_state = `DIV_1;
|
||||||
|
end else begin
|
||||||
|
next_state = `STORE_X;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
`STORE_X: next_state = `DEC_I;
|
||||||
|
`DEC_I: next_state = `I_GT_ZERO;
|
||||||
|
endcase
|
||||||
|
endmodule
|
||||||
|
|
66
cadence/heron_fsm_tb/functional/verilog.v
Normal file
66
cadence/heron_fsm_tb/functional/verilog.v
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
`include "heron_states.v"
|
||||||
|
|
||||||
|
module heron_fsm_tb;
|
||||||
|
task assert;
|
||||||
|
input condition;
|
||||||
|
input [(20*8 - 1):0] message;
|
||||||
|
begin
|
||||||
|
if (condition !== 1'b1)
|
||||||
|
begin
|
||||||
|
$display("Assertion Failed: %s", message);
|
||||||
|
$finish(2);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
parameter CYCLE = 50;
|
||||||
|
|
||||||
|
reg clk, reset;
|
||||||
|
reg load;
|
||||||
|
reg flag_z, flag_c, flag_s;
|
||||||
|
|
||||||
|
wire[3:0] state;
|
||||||
|
|
||||||
|
heron_fsm fsm(
|
||||||
|
.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.load(load),
|
||||||
|
.state(state),
|
||||||
|
.flag_z(flag_z),
|
||||||
|
.flag_c(flag_c),
|
||||||
|
.flag_s(flag_s)
|
||||||
|
);
|
||||||
|
|
||||||
|
initial clk = 1'b0;
|
||||||
|
always #(CYCLE/2) clk = ~clk;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$dumpfile("fsm.vcd");
|
||||||
|
$dumpvars;
|
||||||
|
end
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
reset = 1'b1;
|
||||||
|
#(3*CYCLE)
|
||||||
|
reset = 1'b0;
|
||||||
|
end
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
load = 0;
|
||||||
|
#(5*CYCLE)
|
||||||
|
load = 1;
|
||||||
|
#(CYCLE)
|
||||||
|
load = 0;
|
||||||
|
|
||||||
|
assert(state == `LD_N_1, "IDLE -> LD_N_1");
|
||||||
|
#(CYCLE)
|
||||||
|
assert(state == `LD_N_2, "LD_N_1 -> LD_N_2");
|
||||||
|
#(CYCLE)
|
||||||
|
assert(state == `I_GT_ZERO, "LD_N_2 -> I_GT_ZERO");
|
||||||
|
#(CYCLE)
|
||||||
|
assert(state == `I_GT_ZERO, "LD_N_2 -> I_GT_ZERO");
|
||||||
|
|
||||||
|
$display("FSM tests passed!");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
7
cadence/heron_scaler64_to_32/functional/verilog.v
Normal file
7
cadence/heron_scaler64_to_32/functional/verilog.v
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
module heron_scaler64_to_32 (A,Y);
|
||||||
|
input [63:0] A;
|
||||||
|
output [31:0] Y;
|
||||||
|
wire [31:0] Y;
|
||||||
|
assign Y[30:0] = A[63:33];
|
||||||
|
assign Y[31] = 0;
|
||||||
|
endmodule
|
10
cadence/heron_shift_1/functional/verilog.v
Normal file
10
cadence/heron_shift_1/functional/verilog.v
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
module heron_shift_1 (A, Y);
|
||||||
|
|
||||||
|
input [31:0] A;
|
||||||
|
output [31:0] Y;
|
||||||
|
|
||||||
|
wire [31:0] Y;
|
||||||
|
assign Y[30:0] = A[31:1];
|
||||||
|
assign Y[31] = 0;
|
||||||
|
|
||||||
|
endmodule
|
125
cadence/heron_top_tb/functional/verilog.v
Normal file
125
cadence/heron_top_tb/functional/verilog.v
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
`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
|
Loading…
Reference in New Issue
Block a user