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 bericht: bericht/graph.pdf
latexmk -pdf bericht/bericht.tex; latexmk -pdf bericht/bericht.tex;
fsm: verilog/fsm.vcd fsm: verilog/heron_fsm.vcd
gtkwave verilog/fsm.vcd gtkwave verilog/heron_fsm.vcd
ctrl: verilog/heron_ctrl.vcd
gtkwave verilog/heron_ctrl.vcd
fsm_tb: verilog/heron_fsm.vcd fsm_tb: verilog/heron_fsm.vcd
ctrl_tb: verilog/heron_ctrl.vcd
%.vcd : %.vvp %.vcd : %.vvp
vvp $< vvp $<
%.vvp: %_tb.v %.v %.vvp: %_tb.v %.v
iverilog -o $@ $^ iverilog -o $@ -Iverilog verilog/heron_{fsm,ctrl}.v

View File

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

View File

@ -1,39 +1,197 @@
`include "heron_states.v"
module heron_ctrl( module heron_ctrl(
state, state, // ?
ready, ready, // ?
ram_wr_en, ram_wr_en, // ?
ram_rd_en, ram_rd_en, // ?
alu_mode, alu_mode, //
alu_set_z, alu_set_z, //
alu_set_c, alu_set_c, //
alu_set_s, alu_set_s, //
k0_to_b, k0_to_b, //
k1_to_b, k1_to_b, //
alu_to_b, alu_res_to_a, //
a_to_adr, a_to_adr,
a_to_i, a_to_i, //
a_to_old_x, a_to_old_x, //
a_to_s, a_to_s, //
a_to_x, a_to_x, //
b_to_adr, b_to_adr, // ?
din_to_a, din_to_a, // ?
div_to_b_shift_1, edb_to_din, // ?
i_to_a, a_to_do, // ?
old_x_to_b, div_to_b_shift_1, // ?
s_to_b, i_to_a, //
s_to_b_shift_1, old_x_to_b, //
x_to_a, s_to_b, //
x_to_b_shifted); 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; input [3:0] state;
output ready; output ready;
output ram_wr_en; output ram_wr_en;
output ram_rd_en; output ram_rd_en;
output rom_rd_en;
output alu_mode; 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 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 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); `include "heron_states.v"
// (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;
module heron_fsm(clk, load, reset, flag_z, flag_c, flag_s, state);
input clk; input clk;
input load; input load;
input reset; 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) always @(posedge clk or posedge reset)
if(reset) begin if(reset) begin
state <= IDLE; state <= `IDLE;
end else begin end else begin
state <= next_state; state <= next_state;
end end
always @(state or flag_z or load) always @(state or flag_z or load)
case(state) case(state)
IDLE: `IDLE: begin
if(load) begin if(load) begin
next_state = LD_N_1; next_state = `LD_N_1;
end else begin end else begin
next_state = IDLE; next_state = `IDLE;
end end
LD_N_1: next_state = LD_N_2; end
LD_N_2: next_state = I_GT_ZERO; `LD_N_1: next_state = `LD_N_2;
I_GT_ZERO: `LD_N_2: next_state = `I_GT_ZERO;
`I_GT_ZERO: begin
if (flag_z) begin if (flag_z) begin
next_state = LD_S_1; next_state = `LD_S_1;
end else begin end else begin
next_state = IDLE; next_state = `IDLE;
end end
LD_S_1: next_state = LD_S_2; end
LD_S_2: next_state = S_GT_ONE; `LD_S_1: next_state = `LD_S_2;
S_GT_ONE: `LD_S_2: next_state = `S_GT_ONE;
`S_GT_ONE: begin
if (flag_s || flag_z) begin if (flag_s || flag_z) begin
next_state = STORE_X; next_state = `STORE_X;
end else begin end else begin
next_state = X_1; next_state = `X_1;
end end
X_1: next_state = DIV_2; end
DIV_1: next_state = DIV_2; `X_1: next_state = `DIV_2;
DIV_2: next_state = DIV_3; `DIV_1: next_state = `DIV_2;
DIV_3: next_state = DIV_4; `DIV_2: next_state = `DIV_3;
DIV_4: next_state = OLD_X_LTE_X_1; `DIV_3: next_state = `DIV_4;
OLD_X_LTE_X_1: next_state = OLD_X_LTE_X_2; `DIV_4: next_state = `OLD_X_LTE_X_1;
OLD_X_LTE_X_2: `OLD_X_LTE_X_1: next_state = `OLD_X_LTE_X_2;
`OLD_X_LTE_X_2: begin
if (flag_c) begin if (flag_c) begin
next_state = DIV_1; next_state = `DIV_1;
end else begin end else begin
next_state = STORE_X; next_state = `STORE_X;
end end
STORE_X: next_state = DEC_I; end
DEC_I: next_state = I_GT_ZERO; `STORE_X: next_state = `DEC_I;
`DEC_I: next_state = `I_GT_ZERO;
endcase endcase
end
endmodule endmodule

View File

@ -1,3 +1,5 @@
`include "heron_states.v"
module heron_fsm_tb; module heron_fsm_tb;
task assert; task assert;
input condition; input condition;
@ -50,13 +52,15 @@ module heron_fsm_tb;
#(CYCLE) #(CYCLE)
load = 0; load = 0;
assert(state == fsm.LD_N_1, "IDLE -> LD_N_1"); assert(state == `LD_N_1, "IDLE -> LD_N_1");
#(CYCLE) #(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) #(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; $finish;
end end
endmodule 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