separate reading instructions from reading data

This commit is contained in:
Raphael Jacquot 2019-02-07 08:35:59 +01:00
parent b519f3d8b3
commit b5c3a56273
4 changed files with 149 additions and 87 deletions

16
README
View file

@ -1,3 +1,17 @@
Verilog implementation of the HP saturn processor Verilog implementation of the HP saturn processor
licence: GPLv3 or later licence: GPLv3 or later
timings:
read:
____ ____ ____ ____ ____
clk : ____| |____| |____| |____| |____| |____
_________
address: ____| |_______________________________________
_________
data: _________| |__________________________________
read: ______________|_______________________________________

View file

@ -66,7 +66,7 @@ initial
`ifdef SIM `ifdef SIM
$write("."); $write(".");
`endif `endif
io_ram[base_addr] <= 0; io_ram[base_addr] = 0;
end end
`ifdef SIM `ifdef SIM
$write("\n"); $write("\n");

View file

@ -14309,7 +14309,7 @@
"saturn_core": { "saturn_core": {
"attributes": { "attributes": {
"top": 1, "top": 1,
"src": "saturn_core.v:53" "src": "saturn_core.v:60"
}, },
"ports": { "ports": {
"clk_25mhz": { "clk_25mhz": {
@ -14336,14 +14336,14 @@
"hide_name": 0, "hide_name": 0,
"bits": [ 3, 4, 5, 6, 7, 8, 9 ], "bits": [ 3, 4, 5, 6, 7, 8, 9 ],
"attributes": { "attributes": {
"src": "saturn_core.v:55" "src": "saturn_core.v:62"
} }
}, },
"bus_ctrl.clk": { "bus_ctrl.clk": {
"hide_name": 0, "hide_name": 0,
"bits": [ 2 ], "bits": [ 2 ],
"attributes": { "attributes": {
"src": "saturn_core.v:201|hp48_bus.v:18", "src": "saturn_core.v:208|hp48_bus.v:18",
"unused_bits": "0" "unused_bits": "0"
} }
}, },
@ -14351,7 +14351,7 @@
"hide_name": 0, "hide_name": 0,
"bits": [ 2 ], "bits": [ 2 ],
"attributes": { "attributes": {
"src": "saturn_core.v:201|hp48_bus.v:38|hp48_io_ram.v:16", "src": "saturn_core.v:208|hp48_bus.v:38|hp48_io_ram.v:16",
"unused_bits": "0" "unused_bits": "0"
} }
}, },
@ -14359,7 +14359,7 @@
"hide_name": 0, "hide_name": 0,
"bits": [ 4 ], "bits": [ 4 ],
"attributes": { "attributes": {
"src": "saturn_core.v:201|hp48_bus.v:38|hp48_io_ram.v:17", "src": "saturn_core.v:208|hp48_bus.v:38|hp48_io_ram.v:17",
"unused_bits": "0" "unused_bits": "0"
} }
}, },
@ -14367,7 +14367,7 @@
"hide_name": 0, "hide_name": 0,
"bits": [ 2 ], "bits": [ 2 ],
"attributes": { "attributes": {
"src": "saturn_core.v:201|hp48_bus.v:49|hp48_rom.v:16", "src": "saturn_core.v:208|hp48_bus.v:49|hp48_rom.v:16",
"unused_bits": "0" "unused_bits": "0"
} }
}, },
@ -14375,7 +14375,7 @@
"hide_name": 0, "hide_name": 0,
"bits": [ 4 ], "bits": [ 4 ],
"attributes": { "attributes": {
"src": "saturn_core.v:201|hp48_bus.v:19", "src": "saturn_core.v:208|hp48_bus.v:19",
"unused_bits": "0" "unused_bits": "0"
} }
}, },
@ -14383,7 +14383,7 @@
"hide_name": 0, "hide_name": 0,
"bits": [ 2 ], "bits": [ 2 ],
"attributes": { "attributes": {
"src": "saturn_core.v:59", "src": "saturn_core.v:66",
"unused_bits": "0" "unused_bits": "0"
} }
}, },
@ -14391,21 +14391,21 @@
"hide_name": 0, "hide_name": 0,
"bits": [ 2 ], "bits": [ 2 ],
"attributes": { "attributes": {
"src": "saturn_core.v:54" "src": "saturn_core.v:61"
} }
}, },
"led": { "led": {
"hide_name": 0, "hide_name": 0,
"bits": [ "0", "0", "0", "0", "0", "0", "0", "0" ], "bits": [ "0", "0", "0", "0", "0", "0", "0", "0" ],
"attributes": { "attributes": {
"src": "saturn_core.v:57" "src": "saturn_core.v:64"
} }
}, },
"reset": { "reset": {
"hide_name": 0, "hide_name": 0,
"bits": [ 4 ], "bits": [ 4 ],
"attributes": { "attributes": {
"src": "saturn_core.v:60", "src": "saturn_core.v:67",
"unused_bits": "0" "unused_bits": "0"
} }
}, },
@ -14413,7 +14413,7 @@
"hide_name": 0, "hide_name": 0,
"bits": [ "1" ], "bits": [ "1" ],
"attributes": { "attributes": {
"src": "saturn_core.v:56" "src": "saturn_core.v:63"
} }
} }
} }

View file

@ -21,18 +21,25 @@
* *
*/ */
`define RUN_INIT 0 `define NEXT_INSTR 0
`define NEXT_INSTR 1 `define INSTR_START 1
`define INSTR_STROBE 2
`define INSTR_READY 3
`define READ_START 4 `define READ_START 4
`define READ_STROBE 5 `define READ_STROBE 5
`define READ_DONE 6 `define READ_DONE 6
`define READ_VALUE 7 `define READ_VALUE 7
`define WRITE_START 8 `define WRITE_START 8
`define WRITE_STROBE 9 `define WRITE_STROBE 9
`define WRITE_DONE 11 `define WRITE_DONE 10
`define RUN_DECODE 12 `define RUN_DECODE 12
`define RUN_EXEC 13 `define RUN_EXEC 13
`define RUN_INIT 15
/**************************** /****************************
* *
* runstate * runstate
@ -221,7 +228,6 @@ always @(posedge clk)
// bus // bus
bus_command <= `BUSCMD_NOP; bus_command <= `BUSCMD_NOP;
bus_load_pc <= 0;
// processor state machine // processor state machine
@ -274,8 +280,10 @@ always @(posedge clk)
always @(posedge clk) always @(posedge clk)
if (runstate == `RUN_INIT) if (runstate == `RUN_INIT)
begin begin
bus_command <= `BUSCMD_LOAD_PC; `ifdef SIM
bus_address <= PC; $display("RUN_INIT => NEXT_INSTR");
`endif
bus_load_pc <= 1;
runstate <= `NEXT_INSTR; runstate <= `NEXT_INSTR;
end end
@ -308,28 +316,68 @@ always @(posedge clk)
// //
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
always @(negedge clk)
if ((runstate == `NEXT_INSTR)&(bus_load_pc)) /****
* Instruction data read
*
*
*/
always @(posedge clk)
if (runstate == `NEXT_INSTR)
if (bus_load_pc)
begin
`ifdef SIM
//$display("NEXT_INSTR load PC %5h => INSTR_START", PC);
`endif
bus_address <= PC;
bus_command <= `BUSCMD_LOAD_PC;
bus_load_pc <= 0;
runstate <= `INSTR_START;
end
else
begin
`ifdef SIM
//$display("NEXT_INSTR => INSTR_STROBE");
`endif
bus_command <= `BUSCMD_PC_READ;
runstate <= `INSTR_STROBE;
end
// start reading instruction
always @(posedge clk)
if (runstate == `INSTR_START)
begin begin
`ifdef SIM `ifdef SIM
$display("NEXT_INSTR /clk load PC %5h", PC); //$display("INSTR_START => INSTR_STROBE");
`endif `endif
bus_address <= PC; bus_command <= `BUSCMD_PC_READ;
bus_command <= `BUSCMD_LOAD_PC; runstate <= `INSTR_STROBE;
bus_load_pc <= 0;
end end
// read from rom start
always @(posedge clk) always @(posedge clk)
if ((runstate == `READ_START)|(runstate == `NEXT_INSTR)) if (runstate == `INSTR_STROBE)
begin begin
//$display("READ_START"); `ifdef SIM
bus_command <= `BUSCMD_PC_READ; //$display("INSTR_STROBE => INSTR_READY");
runstate <= `READ_STROBE; `endif
bus_command <= `BUSCMD_NOP;
nibble <= bus_nibble_out;
PC <= PC + 1;
runstate <= `INSTR_READY;
`ifdef SIM
//$display("PC: %h | read => %h", PC, bus_nibble_out);
`endif
end end
/****
*
* read data from bus
*
*/
// read from rom clock in // read from rom clock in
always @(negedge clk) always @(posedge clk)
if (runstate == `READ_STROBE) if (runstate == `READ_STROBE)
begin begin
//$display("READ_STROBE"); //$display("READ_STROBE");
@ -359,7 +407,7 @@ always @(posedge clk)
always @(posedge clk) always @(posedge clk)
begin begin
// first nibble instruction decoder // first nibble instruction decoder
if ((runstate == `READ_VALUE) & (decstate == DECODE_START)) if ((runstate == `INSTR_READY) & (decstate == DECODE_START))
begin begin
//$display("`READ_VALUE -> instruction decoder"); //$display("`READ_VALUE -> instruction decoder");
runstate <= `RUN_DECODE; runstate <= `RUN_DECODE;
@ -390,9 +438,9 @@ begin
if (decstate == DECODE_0) if (decstate == DECODE_0)
case (runstate) case (runstate)
`RUN_DECODE: runstate <= `READ_START; `RUN_DECODE: runstate <= `INSTR_START;
`READ_START, `READ_STROBE, `READ_DONE: begin end `INSTR_START, `INSTR_STROBE: begin end
`READ_VALUE: `INSTR_READY:
case (nibble) case (nibble)
4'h3: decstate <= DECODE_RTNCC; 4'h3: decstate <= DECODE_RTNCC;
4'h4: decstate <= DECODE_SETHEX; 4'h4: decstate <= DECODE_SETHEX;
@ -475,9 +523,9 @@ begin
if (decstate == DECODE_1) if (decstate == DECODE_1)
case (runstate) case (runstate)
`RUN_DECODE: runstate <= `READ_START; `RUN_DECODE: runstate <= `INSTR_START;
`READ_START, `READ_STROBE, `READ_DONE: begin end `INSTR_START, `INSTR_STROBE: begin end
`READ_VALUE: `INSTR_READY:
begin begin
case (nibble) case (nibble)
//4'h4, 4'h5: decode_14_15(); //4'h4, 4'h5: decode_14_15();
@ -526,9 +574,9 @@ begin
if ((decstate == DECODE_14)|(decstate == DECODE_15)) if ((decstate == DECODE_14)|(decstate == DECODE_15))
case (runstate) case (runstate)
`RUN_DECODE: runstate <= `READ_START; `RUN_DECODE: runstate <= `INSTR_START;
`READ_START, `READ_STROBE, `READ_DONE: begin end `INSTR_START, `INSTR_STROBE: begin end
`READ_VALUE: `INSTR_READY:
case (decstate) case (decstate)
DECODE_14: DECODE_14:
begin begin
@ -554,7 +602,7 @@ begin
default: default:
begin begin
`ifdef SIM `ifdef SIM
$display("runstate %h", decstate); $display("DECODE_14_15: runstate %h", decstate);
`endif `endif
halt <= 1; halt <= 1;
end end
@ -651,15 +699,15 @@ begin
case (runstate) case (runstate)
`RUN_DECODE: `RUN_DECODE:
begin begin
runstate <= `READ_START; runstate <= `INSTR_START;
t_cnt <= 4; t_cnt <= 4;
t_ctr <= 0; t_ctr <= 0;
`ifdef SIM `ifdef SIM
$write("%5h D0=(5)\t", saved_PC); $write("%5h D0=(5)\t", saved_PC);
`endif `endif
end end
`READ_START, `READ_STROBE, `READ_DONE: begin end `INSTR_START, `INSTR_STROBE: begin end
`READ_VALUE: `INSTR_READY:
begin begin
D0[t_ctr*4+:4] <= nibble; D0[t_ctr*4+:4] <= nibble;
`ifdef SIM `ifdef SIM
@ -676,13 +724,13 @@ begin
else else
begin begin
t_ctr <= t_ctr + 1; t_ctr <= t_ctr + 1;
runstate <= `READ_START; runstate <= `INSTR_START;
end end
end end
default: default:
begin begin
`ifdef SIM `ifdef SIM
$display("runstate %h", runstate); $display("DECODE_D0_EQ_5N: runstate %h", runstate);
`endif `endif
halt <= 1; halt <= 1;
end end
@ -696,9 +744,9 @@ begin
if (decstate == DECODE_P_EQ) if (decstate == DECODE_P_EQ)
case (runstate) case (runstate)
`RUN_DECODE: runstate <= `READ_START; `RUN_DECODE: runstate <= `INSTR_START;
`READ_START, `READ_STROBE, `READ_DONE: begin end `INSTR_START, `INSTR_STROBE: begin end
`READ_VALUE: `INSTR_READY:
begin begin
P <= nibble; P <= nibble;
`ifdef SIM `ifdef SIM
@ -710,7 +758,7 @@ begin
default: default:
begin begin
`ifdef SIM `ifdef SIM
$display("runstate %h", runstate); $display("DECODE_P_EQ: runstate %h", runstate);
`endif `endif
halt <= 1; halt <= 1;
end end
@ -725,9 +773,9 @@ begin
if ((decstate == DECODE_LC_LEN) | (decstate == DECODE_LC)) if ((decstate == DECODE_LC_LEN) | (decstate == DECODE_LC))
case (runstate) case (runstate)
`RUN_DECODE: runstate <= `READ_START; `RUN_DECODE: runstate <= `INSTR_START;
`READ_START, `READ_STROBE, `READ_DONE: begin end `INSTR_START, `INSTR_STROBE: begin end
`READ_VALUE: `INSTR_READY:
case (decstate) case (decstate)
DECODE_LC_LEN: DECODE_LC_LEN:
begin begin
@ -737,7 +785,7 @@ begin
t_cnt <= nibble; t_cnt <= nibble;
t_ctr <= 0; t_ctr <= 0;
decstate <= DECODE_LC; decstate <= DECODE_LC;
runstate <= `READ_START; runstate <= `INSTR_START;
end end
DECODE_LC: DECODE_LC:
begin begin
@ -757,7 +805,7 @@ begin
else else
begin begin
t_ctr <= (t_ctr + 1)&4'hf; t_ctr <= (t_ctr + 1)&4'hf;
runstate <= `READ_START; runstate <= `INSTR_START;
end end
end end
default: default:
@ -787,14 +835,14 @@ begin
case (runstate) case (runstate)
`RUN_DECODE: `RUN_DECODE:
begin begin
runstate <= `READ_START; runstate <= `INSTR_START;
jump_base <= PC; jump_base <= PC;
jump_offset <= 0; jump_offset <= 0;
t_cnt <= 2; t_cnt <= 2;
t_ctr <= 0; t_ctr <= 0;
end end
`READ_START, `READ_STROBE, `READ_DONE: begin end `INSTR_START, `INSTR_STROBE: begin end
`READ_VALUE: `INSTR_READY:
begin begin
jump_offset[t_ctr*4+:4] <= nibble; jump_offset[t_ctr*4+:4] <= nibble;
if (t_ctr == t_cnt) if (t_ctr == t_cnt)
@ -805,7 +853,7 @@ begin
else else
begin begin
t_ctr <= t_ctr + 1; t_ctr <= t_ctr + 1;
runstate <= `READ_START; runstate <= `INSTR_START;
end end
end end
`RUN_EXEC: `RUN_EXEC:
@ -821,7 +869,7 @@ begin
default: default:
begin begin
`ifdef SIM `ifdef SIM
$display("runstate %h", runstate); $display("DECODE_GOTO: runstate %h", runstate);
`endif `endif
halt <= 1; halt <= 1;
end end
@ -835,9 +883,9 @@ begin
if (decstate == DECODE_8) if (decstate == DECODE_8)
case (runstate) case (runstate)
`RUN_DECODE: runstate <= `READ_START; `RUN_DECODE: runstate <= `INSTR_START;
`READ_START, `READ_STROBE, `READ_DONE: begin end `INSTR_START, `INSTR_STROBE: begin end
`READ_VALUE: `INSTR_READY:
begin begin
case (nibble) case (nibble)
4'h0: decstate <= DECODE_80; 4'h0: decstate <= DECODE_80;
@ -859,7 +907,7 @@ begin
default: default:
begin begin
`ifdef SIM `ifdef SIM
$display("runstate %h", runstate); $display("DECODE_8: runstate %h", runstate);
`endif `endif
halt <= 1; halt <= 1;
end end
@ -873,9 +921,9 @@ begin
if (decstate == DECODE_80) if (decstate == DECODE_80)
case (runstate) case (runstate)
`RUN_DECODE: runstate <= `READ_START; `RUN_DECODE: runstate <= `INSTR_START;
`READ_START, `READ_STROBE, `READ_DONE: begin end `INSTR_START, `INSTR_STROBE: begin end
`READ_VALUE: `INSTR_READY:
begin begin
case (nibble) case (nibble)
4'h5: decstate <= DECODE_CONFIG; 4'h5: decstate <= DECODE_CONFIG;
@ -894,7 +942,7 @@ begin
default: default:
begin begin
`ifdef SIM `ifdef SIM
$display("DECODE_80 runstate %h", runstate); $display("DECODE_80: runstate %h", runstate);
`endif `endif
halt <= 1; halt <= 1;
end end
@ -940,9 +988,9 @@ begin
if (decstate == DECODE_C_EQ_P_N) if (decstate == DECODE_C_EQ_P_N)
case (runstate) case (runstate)
`RUN_DECODE: runstate <= `READ_START; `RUN_DECODE: runstate <= `INSTR_START;
`READ_START, `READ_STROBE, `READ_DONE: begin end `INSTR_START, `INSTR_STROBE: begin end
`READ_VALUE: `INSTR_READY:
begin begin
C[nibble*4+:4] <= P; C[nibble*4+:4] <= P;
`ifdef SIM `ifdef SIM
@ -970,9 +1018,9 @@ begin
if (decstate == DECODE_82) if (decstate == DECODE_82)
case (runstate) case (runstate)
`RUN_DECODE: runstate <= `READ_START; `RUN_DECODE: runstate <= `INSTR_START;
`READ_START, `READ_STROBE, `READ_DONE: begin end `INSTR_START, `INSTR_STROBE: begin end
`READ_VALUE: `INSTR_READY:
begin begin
HST <= HST & ~nibble; HST <= HST & ~nibble;
`ifdef SIM `ifdef SIM
@ -1004,9 +1052,9 @@ begin
if ((decstate == DECODE_ST_EQ_0_N) | (decstate == DECODE_ST_EQ_1_N)) if ((decstate == DECODE_ST_EQ_0_N) | (decstate == DECODE_ST_EQ_1_N))
case (runstate) case (runstate)
`RUN_DECODE: runstate <= `READ_START; `RUN_DECODE: runstate <= `INSTR_START;
`READ_START, `READ_STROBE, `READ_DONE: begin end `INSTR_START, `INSTR_STROBE: begin end
`READ_VALUE: `INSTR_READY:
begin begin
case (decstate) case (decstate)
DECODE_ST_EQ_0_N: DECODE_ST_EQ_0_N:
@ -1051,10 +1099,10 @@ begin
t_ctr <= 0; t_ctr <= 0;
if (decstate == DECODE_GOSBVL) if (decstate == DECODE_GOSBVL)
rstk_ptr <= rstk_ptr + 1; rstk_ptr <= rstk_ptr + 1;
runstate <= `READ_START; runstate <= `INSTR_START;
end end
`READ_START, `READ_STROBE, `READ_DONE: begin end `INSTR_START, `INSTR_STROBE: begin end
`READ_VALUE: `INSTR_READY:
begin begin
//$display("decstate %h | nibble %h", decstate, nibble); //$display("decstate %h | nibble %h", decstate, nibble);
jump_base[t_ctr*4+:4] <= nibble; jump_base[t_ctr*4+:4] <= nibble;
@ -1062,7 +1110,7 @@ begin
else else
begin begin
t_ctr <= t_ctr + 1; t_ctr <= t_ctr + 1;
runstate <= `READ_START; runstate <= `INSTR_START;
end end
end end
`RUN_EXEC: `RUN_EXEC:
@ -1100,15 +1148,15 @@ begin
if ((decstate == DECODE_A)|(decstate == DECODE_A_FS)) if ((decstate == DECODE_A)|(decstate == DECODE_A_FS))
case (runstate) case (runstate)
`RUN_DECODE: runstate <= `READ_START; `RUN_DECODE: runstate <= `INSTR_START;
`READ_START, `READ_STROBE, `READ_DONE: begin end `INSTR_START, `INSTR_STROBE: begin end
`READ_VALUE: `INSTR_READY:
case (decstate) case (decstate)
DECODE_A: DECODE_A:
begin begin
t_field <= nibble; t_field <= nibble;
decstate <= DECODE_A_FS; decstate <= DECODE_A_FS;
runstate <= `READ_START; runstate <= `INSTR_START;
end end
DECODE_A_FS: DECODE_A_FS:
begin begin