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 /hdl | |
| 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 'hdl')
| -rw-r--r-- | hdl/core.sv | 93 |
1 files changed, 90 insertions, 3 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 |
