add control unit

This commit is contained in:
Jörg Thalheim 2014-01-08 16:35:30 +01:00
parent 1d70a432c9
commit a6e02f8e2f
7 changed files with 287 additions and 92 deletions

View File

@ -14,13 +14,17 @@ bericht/graph.pdf: bericht/graph.dot
bericht: bericht/graph.pdf
latexmk -pdf bericht/bericht.tex;
fsm: verilog/fsm.vcd
gtkwave verilog/fsm.vcd
fsm: verilog/heron_fsm.vcd
gtkwave verilog/heron_fsm.vcd
ctrl: verilog/heron_ctrl.vcd
gtkwave verilog/heron_ctrl.vcd
fsm_tb: verilog/heron_fsm.vcd
ctrl_tb: verilog/heron_ctrl.vcd
%.vcd : %.vvp
vvp $<
%.vvp: %_tb.v %.v
iverilog -o $@ $^
iverilog -o $@ -Iverilog verilog/heron_{fsm,ctrl}.v

View File

@ -1,4 +1,4 @@
#
#
#Busse
#
#- BUS_A (Ad)
@ -45,14 +45,14 @@
| | LD_N_2 |
|-----------------------+--------------|
|-------------------+------------------|
| DIN -> BUS_A -> I | NA |
| | N/A - N/A |
| | BC: |
| | -> Z = 0: LD_S_1 |
| | -> Z = 1: IDLE |
| | I_GT_ZERO |
|-------------------+------------------|
|-----------------------+------------------|
| ALU_RES -> BUS_A -> I | NA |
| | N/A - N/A |
| | BC: |
| | -> Z = 0: LD_S_1 |
| | -> Z = 1: IDLE |
| | I_GT_ZERO |
|-----------------------+------------------|
|-------------------+-----------|
| I -> BUS_A -> ADR | DR |
@ -113,12 +113,12 @@
| | DIV_4 |
|---------------------------------+---------------|
|-------------------------+---------------|
| ALU -> BUS_A -> X | N/A |
| ALU -> BUS_A -> ALU_A | SUB - C: SET |
| OLD_X -> BUS_B -> ALU_B | OLD_X_LTE_X_2 |
| | OLD_X_LTE_X_1 |
|-------------------------+---------------|
|---------------------------+---------------|
| ALU_RES -> BUS_A -> X | N/A |
| ALU_RES -> BUS_A -> ALU_A | SUB - C: SET |
| OLD_X -> BUS_B -> ALU_B | OLD_X_LTE_X_2 |
| | OLD_X_LTE_X_1 |
|---------------------------+---------------|
|---------------------+-----------------|
| X -> BUS_A -> OLD_X | N/A |

View File

@ -1,39 +1,197 @@
`include "heron_states.v"
module heron_ctrl(
state,
ready,
ram_wr_en,
ram_rd_en,
alu_mode,
alu_set_z,
alu_set_c,
alu_set_s,
k0_to_b,
k1_to_b,
alu_to_b,
state, // ?
ready, // ?
ram_wr_en, // ?
ram_rd_en, // ?
alu_mode, //
alu_set_z, //
alu_set_c, //
alu_set_s, //
k0_to_b, //
k1_to_b, //
alu_res_to_a, //
a_to_adr,
a_to_i,
a_to_old_x,
a_to_s,
a_to_x,
b_to_adr,
din_to_a,
div_to_b_shift_1,
i_to_a,
old_x_to_b,
s_to_b,
s_to_b_shift_1,
x_to_a,
x_to_b_shifted);
a_to_i, //
a_to_old_x, //
a_to_s, //
a_to_x, //
b_to_adr, // ?
din_to_a, // ?
edb_to_din, // ?
a_to_do, // ?
div_to_b_shift_1, // ?
i_to_a, //
old_x_to_b, //
s_to_b, //
s_to_a_shift_1, //
x_to_a, //
x_to_b_shifted); // ?
// readability
parameter ON = 1'b1;
parameter OFF = 1'b0;
parameter MINUS = 1'b1;
parameter PLUS = 1'b0;
input [3:0] state;
output ready;
output ram_wr_en;
output ram_rd_en;
output rom_rd_en;
output alu_mode;
output alu_set_z;
output alu_set_c;
output alu_set_s;
output k0_to_b;
output k1_to_b;
output alu_res_to_a;
output a_to_adr;
output a_to_i;
output a_to_old_x;
output a_to_s;
output a_to_x;
output b_to_adr;
output din_to_a;
output edb_to_din;
output a_to_do;
output div_to_b_shift_1;
output i_to_a;
output old_x_to_b;
output s_to_b;
output s_to_a_shift_1;
output x_to_a;
output x_to_b_shifted;
reg ready;
reg ram_wr_en;
reg ram_rd_en;
reg rom_rd_en;
reg alu_mode;
reg alu_set_z;
reg alu_set_c;
reg alu_set_s;
reg k0_to_b;
reg k1_to_b;
reg alu_res_to_a;
reg a_to_adr;
reg a_to_i;
reg a_to_old_x;
reg a_to_s;
reg a_to_x;
reg b_to_adr;
reg din_to_a;
reg edb_to_din;
reg a_to_do;
reg div_to_b_shift_1;
reg i_to_a;
reg old_x_to_b;
reg s_to_b;
reg s_to_a_shift_1;
reg x_to_a;
reg x_to_b_shifted;
always @(state) begin
end
ready = OFF;
ram_wr_en = OFF;
ram_rd_en = OFF;
alu_mode = PLUS;
alu_set_z = OFF;
alu_set_c = OFF;
alu_set_s = OFF;
k0_to_b = OFF;
k1_to_b = OFF;
alu_res_to_a = OFF;
a_to_adr = OFF;
a_to_i = OFF;
a_to_old_x = OFF;
a_to_s = OFF;
a_to_x = OFF;
b_to_adr = OFF;
din_to_a = OFF;
edb_to_din = OFF;
div_to_b_shift_1 = OFF;
i_to_a = OFF;
old_x_to_b = OFF;
s_to_b = OFF;
s_to_a_shift_1 = OFF;
x_to_a = OFF;
x_to_b_shifted = OFF;
case (state)
`IDLE: begin
ready = ON;
end
`LD_N_1: begin
k0_to_b = ON;
b_to_adr = ON;
edb_to_din = ON;
ram_rd_en = ON;
end
`LD_N_2: begin
din_to_a = ON;
k0_to_b = ON;
alu_mode = MINUS;
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_adr = 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;
a_to_do = 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
verilog/heron_ctrl_tb.v Normal file
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

@ -1,22 +1,6 @@
module heron_fsm(clk, load, reset, flag_z, flag_c, flag_s, state);
// (C) 1953, Frank Gray
parameter IDLE = 4'b0000;
parameter LD_N_1 = 4'b0001;
parameter LD_N_2 = 4'b0011;
parameter I_GT_ZERO = 4'b0010;
parameter LD_S_1 = 4'b0110;
parameter LD_S_2 = 4'b0111;
parameter S_GT_ONE = 4'b0101;
parameter X_1 = 4'b0100;
parameter DIV_1 = 4'b1100;
parameter DIV_2 = 4'b1101;
parameter DIV_3 = 4'b1111;
parameter DIV_4 = 4'b1110;
parameter OLD_X_LTE_X_1 = 4'b1010;
parameter OLD_X_LTE_X_2 = 4'b1011;
parameter STORE_X = 4'b1001;
parameter DEC_I = 4'b1000;
`include "heron_states.v"
module heron_fsm(clk, load, reset, flag_z, flag_c, flag_s, state);
input clk;
input load;
input reset;
@ -32,49 +16,52 @@ module heron_fsm(clk, load, reset, flag_z, flag_c, flag_s, state);
always @(posedge clk or posedge reset)
if(reset) begin
state <= IDLE;
state <= `IDLE;
end else begin
state <= next_state;
end
always @(state or flag_z or load)
case(state)
IDLE:
`IDLE: begin
if(load) begin
next_state = LD_N_1;
next_state = `LD_N_1;
end else begin
next_state = IDLE;
next_state = `IDLE;
end
LD_N_1: next_state = LD_N_2;
LD_N_2: next_state = I_GT_ZERO;
I_GT_ZERO:
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 = LD_S_1;
next_state = `LD_S_1;
end else begin
next_state = IDLE;
next_state = `IDLE;
end
LD_S_1: next_state = LD_S_2;
LD_S_2: next_state = S_GT_ONE;
S_GT_ONE:
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;
next_state = `STORE_X;
end else begin
next_state = X_1;
next_state = `X_1;
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:
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;
next_state = `DIV_1;
end else begin
next_state = STORE_X;
next_state = `STORE_X;
end
STORE_X: next_state = DEC_I;
DEC_I: next_state = I_GT_ZERO;
end
`STORE_X: next_state = `DEC_I;
`DEC_I: next_state = `I_GT_ZERO;
endcase
end
endmodule

View File

@ -1,3 +1,5 @@
`include "heron_states.v"
module heron_fsm_tb;
task assert;
input condition;
@ -50,13 +52,15 @@ module heron_fsm_tb;
#(CYCLE)
load = 0;
assert(state == fsm.LD_N_1, "IDLE -> LD_N_1");
assert(state == `LD_N_1, "IDLE -> LD_N_1");
#(CYCLE)
assert(state == fsm.LD_N_2, "LD_N_1 -> LD_N_2");
assert(state == `LD_N_2, "LD_N_1 -> LD_N_2");
#(CYCLE)
assert(state == fsm.I_GT_ZERO, "LD_N_2 -> I_GT_ZERO");
assert(state == `I_GT_ZERO, "LD_N_2 -> I_GT_ZERO");
#(CYCLE)
assert(state == `I_GT_ZERO, "LD_N_2 -> I_GT_ZERO");
$display("All tests passed!");
$display("FSM tests passed!");
$finish;
end
endmodule

17
verilog/heron_states.v Normal file
View File

@ -0,0 +1,17 @@
// (C) 1953, Frank Gray
`define IDLE 4'b0000
`define LD_N_1 4'b0001
`define LD_N_2 4'b0011
`define I_GT_ZERO 4'b0010
`define LD_S_1 4'b0110
`define LD_S_2 4'b0111
`define S_GT_ONE 4'b0101
`define X_1 4'b0100
`define DIV_1 4'b1100
`define DIV_2 4'b1101
`define DIV_3 4'b1111
`define DIV_4 4'b1110
`define OLD_X_LTE_X_1 4'b1010
`define OLD_X_LTE_X_2 4'b1011
`define STORE_X 4'b1001
`define DEC_I 4'b1000