add cadence verilog code

This commit is contained in:
Jörg Thalheim 2014-01-18 11:59:04 +01:00
parent c72c930bc0
commit f1d6e026c8
9 changed files with 459 additions and 0 deletions

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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