diff options
| author | Julian Blake Kongslie | 2021-05-02 16:58:46 -0700 |
|---|---|---|
| committer | Julian Blake Kongslie | 2021-05-02 16:58:46 -0700 |
| commit | 529c1cc2496e24c6282c3fa9e0a45272b7f500b6 (patch) | |
| tree | bd604d5a531837a3d39e0759b298b72585843d15 | |
| parent | Fix a few trivial errors with vector sizes, state names, and syntax. (diff) | |
| download | noncpu-529c1cc2496e24c6282c3fa9e0a45272b7f500b6.tar.xz | |
Add a bunch of microcoded instructions.
This is a minimum viable PDP-8 that can print "Hello, world!" and halt.
Diffstat (limited to '')
| -rw-r--r-- | hdl/core.sv | 93 | ||||
| -rw-r--r-- | sim/main.cpp | 21 |
2 files changed, 103 insertions, 11 deletions
diff --git a/hdl/core.sv b/hdl/core.sv index 5bee974..02ff231 100644 --- a/hdl/core.sv +++ b/hdl/core.sv | |||
| @@ -115,6 +115,7 @@ always_ff @(posedge clk) begin | |||
| 115 | if (`lag(mem_read_valid)) begin | 115 | if (`lag(mem_read_valid)) begin |
| 116 | state = FETCH; | 116 | state = FETCH; |
| 117 | {opcode, operand} = `lag(mem_read_data); | 117 | {opcode, operand} = `lag(mem_read_data); |
| 118 | $display("%d decode %x: %b %b", $time, pc-1, opcode, operand); | ||
| 118 | {i, z, wip} = operand; | 119 | {i, z, wip} = operand; |
| 119 | if (z) | 120 | if (z) |
| 120 | address = {page, wip}; | 121 | address = {page, wip}; |
| @@ -130,6 +131,89 @@ always_ff @(posedge clk) begin | |||
| 130 | pc = address; | 131 | pc = address; |
| 131 | end | 132 | end |
| 132 | end | 133 | end |
| 134 | 'b111: begin | ||
| 135 | casez (operand) | ||
| 136 | 'b0????????: begin | ||
| 137 | automatic bit cla, cll, cma, cml, rar, ral, bsw, iac; | ||
| 138 | {cla, cll, cma, cml, rar, ral, bsw, iac} = operand[7:0]; | ||
| 139 | if (cla) acc = 0; | ||
| 140 | if (cll) link = 0; | ||
| 141 | if (cma) acc = ~acc; | ||
| 142 | if (cml) link = ~link; | ||
| 143 | if (iac) {link, acc} += 1; | ||
| 144 | if (rar && !ral) begin | ||
| 145 | {link, acc} = {acc[0], link, acc[11:1]}; | ||
| 146 | if (bsw) {link, acc} = {acc[0], link, acc[11:1]}; | ||
| 147 | end | ||
| 148 | if (ral && !rar) begin | ||
| 149 | {link, acc} = {acc, link}; | ||
| 150 | if (bsw) {link, acc} = {acc, link}; | ||
| 151 | end | ||
| 152 | if (bsw && !(rar || ral)) acc = {acc[5:0], acc[11:6]}; | ||
| 153 | end | ||
| 154 | 'b1????0??0: begin | ||
| 155 | automatic bit cla, sma, sza, snl, osr, hlt; | ||
| 156 | automatic bit skip; | ||
| 157 | {cla, sma, sza, snl, osr, hlt} = {operand[7:4], operand[2:1]}; | ||
| 158 | skip = 0; | ||
| 159 | if (sma && acc[11]) skip = 1; | ||
| 160 | if (sza && acc == 0) skip = 1; | ||
| 161 | if (snl && link != 0) skip = 1; | ||
| 162 | if (skip) pc++; | ||
| 163 | if (cla) acc = 0; | ||
| 164 | if (osr) begin | ||
| 165 | $display("unsupported front panel switch test"); | ||
| 166 | $finish; | ||
| 167 | end | ||
| 168 | if (hlt) state = HALT; | ||
| 169 | end | ||
| 170 | 'b1????1??0: begin | ||
| 171 | automatic bit cla, spa, sna, szl, osr, hlt; | ||
| 172 | automatic bit skip; | ||
| 173 | {cla, spa, sna, szl, osr, hlt} = {operand[7:4], operand[2:1]}; | ||
| 174 | skip = 1; | ||
| 175 | if (spa && acc[11]) skip = 0; | ||
| 176 | if (sna && acc == 0) skip = 0; | ||
| 177 | if (szl && link != 0) skip = 0; | ||
| 178 | if (skip && (spa || sna || szl)) pc++; | ||
| 179 | if (cla) acc = 0; | ||
| 180 | if (osr) begin | ||
| 181 | $display("unsupported front panel switch test"); | ||
| 182 | $finish; | ||
| 183 | end | ||
| 184 | if (hlt) state = HALT; | ||
| 185 | end | ||
| 186 | default: begin | ||
| 187 | $display("%d decoded unknown opcode %x: %b %b", $time, pc-1, opcode, operand); | ||
| 188 | $finish; | ||
| 189 | end | ||
| 190 | endcase | ||
| 191 | end | ||
| 192 | 'b110: begin | ||
| 193 | case (operand[8:3]) | ||
| 194 | 'b000100: begin | ||
| 195 | case (operand[2:0]) | ||
| 196 | 'b001: if (!tx_valid) pc++; | ||
| 197 | 'b110: begin | ||
| 198 | tx_valid = 1; | ||
| 199 | tx_data = {1'b0, acc[6:0]}; | ||
| 200 | end | ||
| 201 | default: begin | ||
| 202 | $display("unsupported device op %b", operand[2:0]); | ||
| 203 | $finish; | ||
| 204 | end | ||
| 205 | endcase | ||
| 206 | end | ||
| 207 | default: begin | ||
| 208 | $display("unsupported device %b", operand[8:3]); | ||
| 209 | $finish; | ||
| 210 | end | ||
| 211 | endcase | ||
| 212 | end | ||
| 213 | default: begin | ||
| 214 | $display("%d decoded unknown opcode %x: %b %b", $time, pc-1, opcode, operand); | ||
| 215 | $finish; | ||
| 216 | end | ||
| 133 | endcase | 217 | endcase |
| 134 | end | 218 | end |
| 135 | end | 219 | end |
| @@ -170,8 +254,8 @@ always_ff @(posedge clk) begin | |||
| 170 | mem_write = 1; | 254 | mem_write = 1; |
| 171 | mem_write_data = address[DATA_BITS-1:0]; | 255 | mem_write_data = address[DATA_BITS-1:0]; |
| 172 | case (opcode) | 256 | case (opcode) |
| 173 | 'b000, 'b001, 'b010: state = `lag(mem_ready) ? PREINC : AGEN; | 257 | 'b000, 'b001, 'b010: state = `lag(mem_ready) ? AGEN : PREINC; |
| 174 | 'b011, 'b100, 'b101: state = `lag(mem_ready) ? PREINC : EXEC; | 258 | 'b011, 'b100, 'b101: state = `lag(mem_ready) ? EXEC : PREINC; |
| 175 | endcase | 259 | endcase |
| 176 | end | 260 | end |
| 177 | 261 | ||
| @@ -231,7 +315,10 @@ always_ff @(posedge clk) begin | |||
| 231 | 315 | ||
| 232 | MEMWAIT: state = `lag(mem_ready) ? FETCH : MEMWAIT; | 316 | MEMWAIT: state = `lag(mem_ready) ? FETCH : MEMWAIT; |
| 233 | 317 | ||
| 234 | HALT: $finish; | 318 | HALT: begin |
| 319 | $display("%d halt state reached", $time); | ||
| 320 | $finish; | ||
| 321 | end | ||
| 235 | endcase | 322 | endcase |
| 236 | end | 323 | end |
| 237 | end | 324 | end |
diff --git a/sim/main.cpp b/sim/main.cpp index f082464..cc1c596 100644 --- a/sim/main.cpp +++ b/sim/main.cpp | |||
| @@ -5,6 +5,13 @@ | |||
| 5 | 5 | ||
| 6 | #include "Vtop.h" | 6 | #include "Vtop.h" |
| 7 | 7 | ||
| 8 | std::uint64_t phases = 0; | ||
| 9 | |||
| 10 | double sc_time_stamp() | ||
| 11 | { | ||
| 12 | return (double)phases / 2; | ||
| 13 | } | ||
| 14 | |||
| 8 | int main(int argc, const char *argv[]) | 15 | int main(int argc, const char *argv[]) |
| 9 | { | 16 | { |
| 10 | Verilated::commandArgs(argc, argv); | 17 | Verilated::commandArgs(argc, argv); |
| @@ -21,31 +28,29 @@ int main(int argc, const char *argv[]) | |||
| 21 | 28 | ||
| 22 | std::cout << "*** RESET SEQUENCE ***\n"; | 29 | std::cout << "*** RESET SEQUENCE ***\n"; |
| 23 | 30 | ||
| 24 | std::uint64_t time = 0; | ||
| 25 | |||
| 26 | top.native_clk = 0; | 31 | top.native_clk = 0; |
| 27 | top.reset_n = 0; | 32 | top.reset_n = 0; |
| 28 | top.eval(); | 33 | top.eval(); |
| 29 | vcd.dump(++time); | 34 | vcd.dump(++phases); |
| 30 | 35 | ||
| 31 | top.native_clk = 1; | 36 | top.native_clk = 1; |
| 32 | top.eval(); | 37 | top.eval(); |
| 33 | vcd.dump(++time); | 38 | vcd.dump(++phases); |
| 34 | 39 | ||
| 35 | top.native_clk = 0; | 40 | top.native_clk = 0; |
| 36 | top.reset_n = 1; | 41 | top.reset_n = 1; |
| 37 | top.eval(); | 42 | top.eval(); |
| 38 | vcd.dump(++time); | 43 | vcd.dump(++phases); |
| 39 | 44 | ||
| 40 | std::cout << "*** MAIN LOOP ***\n"; | 45 | std::cout << "*** MAIN LOOP ***\n"; |
| 41 | 46 | ||
| 42 | for (unsigned int i = 0; i < 100000 && !Verilated::gotFinish(); ++i) { | 47 | for (unsigned int i = 0; i < 10000 && !Verilated::gotFinish(); ++i) { |
| 43 | top.native_clk = 1; | 48 | top.native_clk = 1; |
| 44 | top.eval(); | 49 | top.eval(); |
| 45 | vcd.dump(++time); | 50 | vcd.dump(++phases); |
| 46 | top.native_clk = 0; | 51 | top.native_clk = 0; |
| 47 | top.eval(); | 52 | top.eval(); |
| 48 | vcd.dump(++time); | 53 | vcd.dump(++phases); |
| 49 | } | 54 | } |
| 50 | 55 | ||
| 51 | std::cout << "\n"; | 56 | std::cout << "\n"; |
