summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoruvok2026-01-22 20:46:11 +0100
committeruvok2026-01-22 20:46:11 +0100
commite99939491820df300a6179719d807f810e7f1680 (patch)
tree1712d3bd2e92de92a76e7575417aeb600b1871d7
parent53a87c78df525068ea0d850676bea2a41fcd7bc5 (diff)
eater: PC inc included, decode on negedgemain
Some cycles can be saved. As previously (wrongly) committed, the PC can be incremented early, but the decoder needs to do this "early", so as now implemented, on the falling clock adge already.
-rw-r--r--eater_cpu/cpp/Veater_computer__main.cpp7
-rw-r--r--eater_cpu/eater_computer.sv5
-rw-r--r--eater_cpu/eater_decoder.sv21
-rw-r--r--eater_cpu/eater_types.sv5
-rw-r--r--eater_cpu/readme.txt3
5 files changed, 28 insertions, 13 deletions
diff --git a/eater_cpu/cpp/Veater_computer__main.cpp b/eater_cpu/cpp/Veater_computer__main.cpp
index b4cd413..40b39b3 100644
--- a/eater_cpu/cpp/Veater_computer__main.cpp
+++ b/eater_cpu/cpp/Veater_computer__main.cpp
@@ -22,11 +22,12 @@ void load_program(const std::unique_ptr<Veater_computer> &topp) {
0x1e,
// ADD 15
0x2f,
- // SUB 13
- 0x3d,
// STA 12
0x4c,
-
+ // SUB 13
+ 0x3d,
+ // STA 11
+ 0x4b,
// OUT
0xe0,
// LDI 4
diff --git a/eater_cpu/eater_computer.sv b/eater_cpu/eater_computer.sv
index 6569831..2fca29e 100644
--- a/eater_cpu/eater_computer.sv
+++ b/eater_cpu/eater_computer.sv
@@ -167,8 +167,11 @@ eater_register OUT (
.always_out(OUT_out)
);
+// run decoder on negated clock,
+// allowing stuff to be clocked in "early"
+wire DEC_clk_neg = ~clk_in;
eater_decoder decoder (
- .clk_i(clk_in),
+ .clk_i(DEC_clk_neg),
.instruction_i(INS_out),
.flags_o(automatic_flags)
);
diff --git a/eater_cpu/eater_decoder.sv b/eater_cpu/eater_decoder.sv
index 634102a..e18d20d 100644
--- a/eater_cpu/eater_decoder.sv
+++ b/eater_cpu/eater_decoder.sv
@@ -47,11 +47,12 @@ always @(posedge clk_i) begin
INIT: next_state = PC_to_MAR;
- PC_to_MAR: next_state = MEM_to_INS;
+ // PC_to_MAR: next_state = MEM_to_INS;
+ // MEM_to_INS: next_state = PC_inc;
+ // PC_inc: next_state = insdep_state();
- MEM_to_INS: next_state = PC_inc;
-
- PC_inc: next_state = insdep_state();
+ PC_to_MAR: next_state = MEM_to_INS_PC_inc;
+ MEM_to_INS_PC_inc: next_state = insdep_state();
LDA_INS_to_MAR: next_state = LDA_MEM_to_A;
LDA_MEM_to_A: next_state = PC_to_MAR;
@@ -101,11 +102,17 @@ always_comb begin
internal_flags.PC_out = 1;
internal_flags.MAR_in = 1;
end
- MEM_to_INS: begin
+ // MEM_to_INS: begin
+ // internal_flags.RAM_out = 1;
+ // internal_flags.INS_in = 1;
+ // end
+ // PC_inc: begin
+ // internal_flags.PC_count = 1;
+ // end
+
+ MEM_to_INS_PC_inc: begin
internal_flags.RAM_out = 1;
internal_flags.INS_in = 1;
- end
- PC_inc: begin
internal_flags.PC_count = 1;
end
diff --git a/eater_cpu/eater_types.sv b/eater_cpu/eater_types.sv
index bff9abc..c7f0cf0 100644
--- a/eater_cpu/eater_types.sv
+++ b/eater_cpu/eater_types.sv
@@ -8,7 +8,7 @@ typedef enum logic[7:0] {
// "regular" states
INIT,
PC_to_MAR,
- MEM_to_INS,
+ MEM_to_INS_PC_inc,
// Note:
// The Ben Eater CPU combines these steps. However.
// I got probably a bug in my state machine,
@@ -16,7 +16,8 @@ typedef enum logic[7:0] {
// but if I combine the steps, I'm trying to get
// the instruction-dependent next state before
// the INS is actually loaded. whoops.
- PC_inc,
+ // One day later: Possible if we run the decoder on the negedge
+ // PC_inc,
// instruction dependent states
diff --git a/eater_cpu/readme.txt b/eater_cpu/readme.txt
index e4b28cd..44ae2d2 100644
--- a/eater_cpu/readme.txt
+++ b/eater_cpu/readme.txt
@@ -54,6 +54,9 @@ operation
Yes, I know Ben Eaters computer combines b and c.
See eater_types for details.
+ Actually, it occurred to me you can combine b and c,
+ if you like BE PC, run the decoder on the falling clock edge.
+
2. Decode and execute instruction.
2.I LDA: Load memory into A