diff options
| author | uvok | 2026-01-22 20:46:11 +0100 |
|---|---|---|
| committer | uvok | 2026-01-22 20:46:11 +0100 |
| commit | e99939491820df300a6179719d807f810e7f1680 (patch) | |
| tree | 1712d3bd2e92de92a76e7575417aeb600b1871d7 | |
| parent | 53a87c78df525068ea0d850676bea2a41fcd7bc5 (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.cpp | 7 | ||||
| -rw-r--r-- | eater_cpu/eater_computer.sv | 5 | ||||
| -rw-r--r-- | eater_cpu/eater_decoder.sv | 21 | ||||
| -rw-r--r-- | eater_cpu/eater_types.sv | 5 | ||||
| -rw-r--r-- | eater_cpu/readme.txt | 3 |
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 |
