add control unit
This commit is contained in:
parent
1d70a432c9
commit
a6e02f8e2f
10
Makefile
10
Makefile
@ -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
|
||||||
|
@ -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 |
|
||||||
|
@ -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
25
verilog/heron_ctrl_tb.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
|
@ -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
|
||||||
|
@ -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
17
verilog/heron_states.v
Normal 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
|
Loading…
Reference in New Issue
Block a user