diff options
| author | Julian Blake Kongslie | 2021-10-31 13:47:24 -0700 |
|---|---|---|
| committer | Julian Blake Kongslie | 2021-10-31 13:47:24 -0700 |
| commit | fda3a38b998908ad584006a6d21b176e806575c7 (patch) | |
| tree | 342fc9f3ae13b53f60f4ea9323dd235b89e632a3 /hdl | |
| parent | Fix the hello.pal program that we broke. (diff) | |
| download | noncpu-fda3a38b998908ad584006a6d21b176e806575c7.tar.xz | |
Implement single-stepping the core.
Diffstat (limited to '')
| -rw-r--r-- | hdl/core.sv | 484 | ||||
| -rw-r--r-- | hdl/top.sv | 3 |
2 files changed, 257 insertions, 230 deletions
diff --git a/hdl/core.sv b/hdl/core.sv index eceea78..43a4a1a 100644 --- a/hdl/core.sv +++ b/hdl/core.sv | |||
| @@ -8,6 +8,9 @@ module core | |||
| 8 | , input bit reset | 8 | , input bit reset |
| 9 | 9 | ||
| 10 | , input bit switch_cont | 10 | , input bit switch_cont |
| 11 | , input bit switch_stop | ||
| 12 | , input bit switch_sing_step | ||
| 13 | , input bit switch_sing_inst | ||
| 11 | 14 | ||
| 12 | // verilator lint_off UNDRIVEN | 15 | // verilator lint_off UNDRIVEN |
| 13 | , output bit [ADDR_BITS-1:0] led_pc | 16 | , output bit [ADDR_BITS-1:0] led_pc |
| @@ -40,6 +43,7 @@ module core | |||
| 40 | ); | 43 | ); |
| 41 | 44 | ||
| 42 | bit run; | 45 | bit run; |
| 46 | bit switch_cont_observed; | ||
| 43 | assign led_run = run; | 47 | assign led_run = run; |
| 44 | 48 | ||
| 45 | bit mem_ready; | 49 | bit mem_ready; |
| @@ -47,6 +51,7 @@ bit mem_valid; | |||
| 47 | bit mem_write; | 51 | bit mem_write; |
| 48 | bit [ADDR_BITS-1:0] mem_address; | 52 | bit [ADDR_BITS-1:0] mem_address; |
| 49 | bit [DATA_BITS-1:0] mem_write_data; | 53 | bit [DATA_BITS-1:0] mem_write_data; |
| 54 | assign led_current_address = mem_valid; | ||
| 50 | 55 | ||
| 51 | assign led_df = 0; | 56 | assign led_df = 0; |
| 52 | assign led_if = 0; | 57 | assign led_if = 0; |
| @@ -106,7 +111,6 @@ bit [8:0] operand; | |||
| 106 | bit [DATA_BITS-1:0] acc; | 111 | bit [DATA_BITS-1:0] acc; |
| 107 | bit link; | 112 | bit link; |
| 108 | 113 | ||
| 109 | assign led_pc = pc; | ||
| 110 | assign led_acc = acc; | 114 | assign led_acc = acc; |
| 111 | assign led_link = link; | 115 | assign led_link = link; |
| 112 | 116 | ||
| @@ -147,17 +151,28 @@ assign led_pause = state == MEMWAIT || state == HALT; | |||
| 147 | always_ff @(posedge clk) begin | 151 | always_ff @(posedge clk) begin |
| 148 | if (reset) begin | 152 | if (reset) begin |
| 149 | run = 0; | 153 | run = 0; |
| 154 | switch_cont_observed = 0; | ||
| 150 | mem_valid = 0; | 155 | mem_valid = 0; |
| 151 | rx_ready = 0; | 156 | rx_ready = 0; |
| 152 | tx_valid = 0; | 157 | tx_valid = 0; |
| 153 | tx_data = 0; | 158 | tx_data = 0; |
| 154 | pc = 'o200; | 159 | pc = 'o200; |
| 160 | led_pc = pc; | ||
| 155 | acc = 0; | 161 | acc = 0; |
| 156 | link = 1; | 162 | link = 1; |
| 157 | kbd_valid = 0; | 163 | kbd_valid = 0; |
| 158 | state = state.first; | 164 | state = state.first; |
| 159 | end else if (run || switch_cont) begin | 165 | end else begin |
| 160 | run = 1; | 166 | if (switch_cont && !switch_cont_observed) begin |
| 167 | run = 1; | ||
| 168 | switch_cont_observed = 1; | ||
| 169 | end | ||
| 170 | |||
| 171 | if (!switch_cont) | ||
| 172 | switch_cont_observed = 0; | ||
| 173 | |||
| 174 | if (switch_stop) | ||
| 175 | run = 0; | ||
| 161 | 176 | ||
| 162 | if (`lag(tx_ready)) tx_valid = 0; | 177 | if (`lag(tx_ready)) tx_valid = 0; |
| 163 | if (rx_ready && `lag(rx_valid)) begin | 178 | if (rx_ready && `lag(rx_valid)) begin |
| @@ -165,259 +180,268 @@ always_ff @(posedge clk) begin | |||
| 165 | kbd_data = {4'b0, 1'b1, `lag(rx_data[6:0])}; | 180 | kbd_data = {4'b0, 1'b1, `lag(rx_data[6:0])}; |
| 166 | end | 181 | end |
| 167 | 182 | ||
| 168 | case (state) | 183 | if (run) begin |
| 169 | FETCH: begin | 184 | case (state) |
| 170 | mem_valid = 1; | 185 | FETCH: begin |
| 171 | mem_address = pc; | 186 | mem_valid = 1; |
| 172 | mem_write = 0; | 187 | mem_address = pc; |
| 173 | if (`lag(mem_ready)) begin | 188 | mem_write = 0; |
| 174 | state = DECODE; | 189 | if (`lag(mem_ready)) begin |
| 175 | page = pc[ADDR_BITS-1:7]; | 190 | state = DECODE; |
| 176 | ++pc; | 191 | page = pc[ADDR_BITS-1:7]; |
| 192 | led_pc = pc; | ||
| 193 | ++pc; | ||
| 194 | end | ||
| 177 | end | 195 | end |
| 178 | end | ||
| 179 | 196 | ||
| 180 | DECODE: begin | 197 | DECODE: begin |
| 181 | mem_valid = 0; | 198 | mem_valid = 0; |
| 182 | mem_write = 0; | 199 | mem_write = 0; |
| 183 | if (`lag(mem_read_valid)) begin | 200 | if (`lag(mem_read_valid)) begin |
| 184 | state = FETCH; | 201 | state = FETCH; |
| 185 | led_memdata = `lag(mem_read_data); | 202 | led_memdata = `lag(mem_read_data); |
| 186 | {opcode, operand} = `lag(mem_read_data); | 203 | {opcode, operand} = `lag(mem_read_data); |
| 187 | // $display("%o: decode %o %o", pc-1, opcode, operand); | 204 | // $display("%o: decode %o %o", pc-1, opcode, operand); |
| 188 | // verilator lint_off WIDTH | 205 | // verilator lint_off WIDTH |
| 189 | // $display("%o %b %o 0000", 14'(pc-1), link, acc); | 206 | // $display("%o %b %o 0000", 14'(pc-1), link, acc); |
| 190 | // verilator lint_on WIDTH | 207 | // verilator lint_on WIDTH |
| 191 | {i, z, wip} = operand; | 208 | {i, z, wip} = operand; |
| 192 | if (z) | 209 | if (z) |
| 193 | address = {page, wip}; | 210 | address = {page, wip}; |
| 194 | else | 211 | else |
| 195 | address = {5'b0, wip}; | 212 | address = {5'b0, wip}; |
| 196 | case (opcode) | 213 | case (opcode) |
| 197 | 'o0, 'o1, 'o2: state = i ? INDIRECT : AGEN; | 214 | 'o0, 'o1, 'o2: state = i ? INDIRECT : AGEN; |
| 198 | 'o3, 'o4: state = i ? INDIRECT : EXEC; | 215 | 'o3, 'o4: state = i ? INDIRECT : EXEC; |
| 199 | 'o5: begin | 216 | 'o5: begin |
| 200 | if (i) begin | 217 | if (i) begin |
| 201 | state = INDIRECT; | 218 | state = INDIRECT; |
| 202 | end else begin | 219 | end else begin |
| 203 | pc = address; | 220 | pc = address; |
| 204 | end | ||
| 205 | end | ||
| 206 | 'o7: begin | ||
| 207 | casez (operand) | ||
| 208 | 'b0????????: begin | ||
| 209 | automatic bit cla, cll, cma, cml, rar, ral, bsw, iac; | ||
| 210 | {cla, cll, cma, cml, rar, ral, bsw, iac} = operand[7:0]; | ||
| 211 | if (cla) acc = 0; | ||
| 212 | if (cll) link = 0; | ||
| 213 | if (cma) acc = ~acc; | ||
| 214 | if (cml) link = ~link; | ||
| 215 | if (iac) {link, acc} += 1; | ||
| 216 | if (rar && !ral) begin | ||
| 217 | {link, acc} = {acc[0], link, acc[11:1]}; | ||
| 218 | if (bsw) {link, acc} = {acc[0], link, acc[11:1]}; | ||
| 219 | end | ||
| 220 | if (ral && !rar) begin | ||
| 221 | {link, acc} = {acc, link}; | ||
| 222 | if (bsw) {link, acc} = {acc, link}; | ||
| 223 | end | ||
| 224 | if (bsw && !(rar || ral)) acc = {acc[5:0], acc[11:6]}; | ||
| 225 | end | ||
| 226 | 'b1????0??0: begin | ||
| 227 | automatic bit cla, sma, sza, snl, osr, hlt; | ||
| 228 | automatic bit skip; | ||
| 229 | {cla, sma, sza, snl, osr, hlt} = {operand[7:4], operand[2:1]}; | ||
| 230 | skip = 0; | ||
| 231 | if (sma && acc[11]) skip = 1; | ||
| 232 | if (sza && acc == 0) skip = 1; | ||
| 233 | if (snl && link != 0) skip = 1; | ||
| 234 | if (skip) pc++; | ||
| 235 | if (cla) acc = 0; | ||
| 236 | if (osr) begin | ||
| 237 | $display("%o: unsupported front panel switch test", pc); | ||
| 238 | $finish; | ||
| 239 | end | ||
| 240 | if (hlt) state = HALT; | ||
| 241 | end | ||
| 242 | 'b1????1??0: begin | ||
| 243 | automatic bit cla, spa, sna, szl, osr, hlt; | ||
| 244 | automatic bit skip; | ||
| 245 | {cla, spa, sna, szl, osr, hlt} = {operand[7:4], operand[2:1]}; | ||
| 246 | skip = 1; | ||
| 247 | if (spa && acc[11]) skip = 0; | ||
| 248 | if (sna && acc == 0) skip = 0; | ||
| 249 | if (szl && link != 0) skip = 0; | ||
| 250 | if (skip) pc++; | ||
| 251 | if (cla) acc = 0; | ||
| 252 | if (osr) begin | ||
| 253 | $display("%o: unsupported front panel switch test", pc); | ||
| 254 | $finish; | ||
| 255 | end | ||
| 256 | if (hlt) state = HALT; | ||
| 257 | end | ||
| 258 | default: begin | ||
| 259 | $display("%o: decoded unknown opcode %o %o", pc-1, opcode, operand); | ||
| 260 | $finish; | ||
| 261 | end | ||
| 262 | endcase | ||
| 263 | end | ||
| 264 | 'o6: begin | ||
| 265 | case (operand[8:3]) | ||
| 266 | 'o00: begin | ||
| 267 | case (operand[2:0]) | ||
| 268 | 'o0, 'o1: ; | ||
| 269 | default: $display("%o: unsupported 600%o op", pc-1, operand[2:0]); | ||
| 270 | endcase | ||
| 271 | end | 221 | end |
| 272 | 'o03: begin | 222 | end |
| 273 | case (operand[2:0]) | 223 | 'o7: begin |
| 274 | 'o1: if (kbd_valid) pc++; | 224 | casez (operand) |
| 275 | 'o6: begin | 225 | 'b0????????: begin |
| 276 | acc = kbd_data; | 226 | automatic bit cla, cll, cma, cml, rar, ral, bsw, iac; |
| 277 | kbd_valid = 0; | 227 | {cla, cll, cma, cml, rar, ral, bsw, iac} = operand[7:0]; |
| 228 | if (cla) acc = 0; | ||
| 229 | if (cll) link = 0; | ||
| 230 | if (cma) acc = ~acc; | ||
| 231 | if (cml) link = ~link; | ||
| 232 | if (iac) {link, acc} += 1; | ||
| 233 | if (rar && !ral) begin | ||
| 234 | {link, acc} = {acc[0], link, acc[11:1]}; | ||
| 235 | if (bsw) {link, acc} = {acc[0], link, acc[11:1]}; | ||
| 278 | end | 236 | end |
| 279 | default: begin | 237 | if (ral && !rar) begin |
| 280 | $display("%o: unsupported keyboard op %o", pc-1, operand[2:0]); | 238 | {link, acc} = {acc, link}; |
| 281 | $finish; | 239 | if (bsw) {link, acc} = {acc, link}; |
| 282 | end | 240 | end |
| 283 | endcase | 241 | if (bsw && !(rar || ral)) acc = {acc[5:0], acc[11:6]}; |
| 284 | end | 242 | end |
| 285 | 'o04: begin | 243 | 'b1????0??0: begin |
| 286 | case (operand[2:0]) | 244 | automatic bit cla, sma, sza, snl, osr, hlt; |
| 287 | 'o1: if (!tx_valid) pc++; | 245 | automatic bit skip; |
| 288 | 'o6: begin | 246 | {cla, sma, sza, snl, osr, hlt} = {operand[7:4], operand[2:1]}; |
| 289 | tx_valid = 1; | 247 | skip = 0; |
| 290 | tx_data = {1'b0, acc[6:0]}; | 248 | if (sma && acc[11]) skip = 1; |
| 249 | if (sza && acc == 0) skip = 1; | ||
| 250 | if (snl && link != 0) skip = 1; | ||
| 251 | if (skip) pc++; | ||
| 252 | if (cla) acc = 0; | ||
| 253 | if (osr) begin | ||
| 254 | $display("%o: unsupported front panel switch test", pc); | ||
| 255 | $finish; | ||
| 291 | end | 256 | end |
| 292 | default: begin | 257 | if (hlt) state = HALT; |
| 293 | $display("%o: unsupported tty op %o", pc-1, operand[2:0]); | 258 | end |
| 259 | 'b1????1??0: begin | ||
| 260 | automatic bit cla, spa, sna, szl, osr, hlt; | ||
| 261 | automatic bit skip; | ||
| 262 | {cla, spa, sna, szl, osr, hlt} = {operand[7:4], operand[2:1]}; | ||
| 263 | skip = 1; | ||
| 264 | if (spa && acc[11]) skip = 0; | ||
| 265 | if (sna && acc == 0) skip = 0; | ||
| 266 | if (szl && link != 0) skip = 0; | ||
| 267 | if (skip) pc++; | ||
| 268 | if (cla) acc = 0; | ||
| 269 | if (osr) begin | ||
| 270 | $display("%o: unsupported front panel switch test", pc); | ||
| 294 | $finish; | 271 | $finish; |
| 295 | end | 272 | end |
| 296 | endcase | 273 | if (hlt) state = HALT; |
| 297 | end | 274 | end |
| 298 | default: begin | 275 | default: begin |
| 299 | $display("%o: unsupported device %o (operation %o)", pc-1, operand[8:3], operand[2:0]); | 276 | $display("%o: decoded unknown opcode %o %o", pc-1, opcode, operand); |
| 277 | $finish; | ||
| 278 | end | ||
| 279 | endcase | ||
| 280 | end | ||
| 281 | 'o6: begin | ||
| 282 | case (operand[8:3]) | ||
| 283 | 'o00: begin | ||
| 284 | case (operand[2:0]) | ||
| 285 | 'o0, 'o1: ; | ||
| 286 | default: $display("%o: unsupported 600%o op", pc-1, operand[2:0]); | ||
| 287 | endcase | ||
| 288 | end | ||
| 289 | 'o03: begin | ||
| 290 | case (operand[2:0]) | ||
| 291 | 'o1: if (kbd_valid) pc++; | ||
| 292 | 'o6: begin | ||
| 293 | acc = kbd_data; | ||
| 294 | kbd_valid = 0; | ||
| 295 | end | ||
| 296 | default: begin | ||
| 297 | $display("%o: unsupported keyboard op %o", pc-1, operand[2:0]); | ||
| 298 | $finish; | ||
| 299 | end | ||
| 300 | endcase | ||
| 301 | end | ||
| 302 | 'o04: begin | ||
| 303 | case (operand[2:0]) | ||
| 304 | 'o1: if (!tx_valid) pc++; | ||
| 305 | 'o6: begin | ||
| 306 | tx_valid = 1; | ||
| 307 | tx_data = {1'b0, acc[6:0]}; | ||
| 308 | end | ||
| 309 | default: begin | ||
| 310 | $display("%o: unsupported tty op %o", pc-1, operand[2:0]); | ||
| 311 | $finish; | ||
| 312 | end | ||
| 313 | endcase | ||
| 314 | end | ||
| 315 | default: begin | ||
| 316 | $display("%o: unsupported device %o (operation %o)", pc-1, operand[8:3], operand[2:0]); | ||
| 317 | end | ||
| 318 | endcase | ||
| 319 | end | ||
| 320 | default: begin | ||
| 321 | $display("%o: decoded unknown opcode %o %o", pc-1, opcode, operand); | ||
| 322 | $finish; | ||
| 323 | end | ||
| 324 | endcase | ||
| 325 | end | ||
| 326 | end | ||
| 327 | |||
| 328 | INDIRECT: begin | ||
| 329 | mem_valid = 1; | ||
| 330 | mem_write = 0; | ||
| 331 | mem_address = address; | ||
| 332 | state = `lag(mem_ready) ? INDIRECTED : INDIRECT; | ||
| 333 | end | ||
| 334 | |||
| 335 | INDIRECTED: begin | ||
| 336 | if (`lag(mem_ready)) begin | ||
| 337 | mem_valid = 0; | ||
| 338 | mem_write = 0; | ||
| 339 | end | ||
| 340 | if (`lag(mem_read_valid)) begin | ||
| 341 | if (address[7:3] == 5'b00001) begin | ||
| 342 | led_memdata = `lag(mem_read_data); | ||
| 343 | address = {{(ADDR_BITS - DATA_BITS){1'b0}}, `lag(mem_read_data)}; | ||
| 344 | address += 1; | ||
| 345 | state = PREINC; | ||
| 346 | end else begin | ||
| 347 | led_memdata = `lag(mem_read_data); | ||
| 348 | address = {{(ADDR_BITS - DATA_BITS){1'b0}}, `lag(mem_read_data)}; | ||
| 349 | case (opcode) | ||
| 350 | 'o0, 'o1, 'o2: state = AGEN; | ||
| 351 | 'o3, 'o4: state = EXEC; | ||
| 352 | 'o5: begin | ||
| 353 | pc = address; | ||
| 354 | state = FETCH; | ||
| 300 | end | 355 | end |
| 301 | endcase | 356 | endcase |
| 302 | end | 357 | end |
| 303 | default: begin | 358 | end |
| 304 | $display("%o: decoded unknown opcode %o %o", pc-1, opcode, operand); | ||
| 305 | $finish; | ||
| 306 | end | ||
| 307 | endcase | ||
| 308 | end | 359 | end |
| 309 | end | ||
| 310 | 360 | ||
| 311 | INDIRECT: begin | 361 | PREINC: begin |
| 312 | mem_valid = 1; | 362 | mem_valid = 1; |
| 313 | mem_write = 0; | 363 | mem_write = 1; |
| 314 | mem_address = address; | 364 | mem_write_data = address[DATA_BITS-1:0]; |
| 315 | state = `lag(mem_ready) ? INDIRECTED : INDIRECT; | 365 | led_memdata = mem_write_data; |
| 316 | end | 366 | case (opcode) |
| 367 | 'o0, 'o1, 'o2: state = `lag(mem_ready) ? AGEN : PREINC; | ||
| 368 | 'o3, 'o4, 'o5: state = `lag(mem_ready) ? EXEC : PREINC; | ||
| 369 | endcase | ||
| 370 | end | ||
| 317 | 371 | ||
| 318 | INDIRECTED: begin | 372 | AGEN: begin |
| 319 | if (`lag(mem_ready)) begin | 373 | mem_valid = 1; |
| 320 | mem_valid = 0; | 374 | case (opcode) |
| 321 | mem_write = 0; | 375 | 'o0, 'o1, 'o2: mem_write = 0; |
| 376 | endcase | ||
| 377 | mem_address = address; | ||
| 378 | state = `lag(mem_ready) ? EXEC : AGEN; | ||
| 322 | end | 379 | end |
| 323 | if (`lag(mem_read_valid)) begin | 380 | |
| 324 | if (address[7:3] == 5'b00001) begin | 381 | EXEC: begin |
| 325 | led_memdata = `lag(mem_read_data); | 382 | automatic bit stall = 0; |
| 326 | address = {{(ADDR_BITS - DATA_BITS){1'b0}}, `lag(mem_read_data)}; | 383 | if (`lag(mem_ready)) begin |
| 327 | address += 1; | 384 | mem_valid = 0; |
| 328 | state = PREINC; | 385 | mem_write = 0; |
| 329 | end else begin | 386 | end else if (mem_valid) begin |
| 330 | led_memdata = `lag(mem_read_data); | 387 | stall = 1; |
| 331 | address = {{(ADDR_BITS - DATA_BITS){1'b0}}, `lag(mem_read_data)}; | 388 | end |
| 389 | case (opcode) | ||
| 390 | 'o0, 'o1, 'o2: if (! `lag(mem_read_valid)) stall = 1; | ||
| 391 | endcase | ||
| 392 | if (! stall) begin | ||
| 393 | state = FETCH; | ||
| 332 | case (opcode) | 394 | case (opcode) |
| 333 | 'o0, 'o1, 'o2: state = AGEN; | 395 | 'o0: begin led_memdata = `lag(mem_read_data); acc &= `lag(mem_read_data); end |
| 334 | 'o3, 'o4: state = EXEC; | 396 | 'o1: begin led_memdata = `lag(mem_read_data); {link, acc} += {1'b0, `lag(mem_read_data)}; end |
| 335 | 'o5: begin | 397 | 'o2: begin |
| 336 | pc = address; | 398 | mem_valid = 1; |
| 337 | state = FETCH; | 399 | mem_address = address; |
| 400 | mem_write = 1; | ||
| 401 | mem_write_data = `lag(mem_read_data) + 1; | ||
| 402 | led_memdata = mem_write_data; | ||
| 403 | if (mem_write_data == 0) ++pc; | ||
| 404 | state = MEMWAIT; | ||
| 405 | end | ||
| 406 | 'o3: begin | ||
| 407 | mem_valid = 1; | ||
| 408 | mem_address = address; | ||
| 409 | mem_write = 1; | ||
| 410 | mem_write_data = acc; | ||
| 411 | led_memdata = mem_write_data; | ||
| 412 | acc = 0; | ||
| 413 | state = MEMWAIT; | ||
| 338 | end | 414 | end |
| 415 | 'o4: begin | ||
| 416 | mem_valid = 1; | ||
| 417 | mem_address = address; | ||
| 418 | mem_write = 1; | ||
| 419 | mem_write_data = pc[DATA_BITS-1:0]; | ||
| 420 | led_memdata = mem_write_data; | ||
| 421 | pc = address + 1; | ||
| 422 | state = MEMWAIT; | ||
| 423 | end | ||
| 424 | 'o5: pc = address; | ||
| 339 | endcase | 425 | endcase |
| 340 | end | 426 | end |
| 341 | end | 427 | end |
| 342 | end | ||
| 343 | |||
| 344 | PREINC: begin | ||
| 345 | mem_valid = 1; | ||
| 346 | mem_write = 1; | ||
| 347 | mem_write_data = address[DATA_BITS-1:0]; | ||
| 348 | led_memdata = mem_write_data; | ||
| 349 | case (opcode) | ||
| 350 | 'o0, 'o1, 'o2: state = `lag(mem_ready) ? AGEN : PREINC; | ||
| 351 | 'o3, 'o4, 'o5: state = `lag(mem_ready) ? EXEC : PREINC; | ||
| 352 | endcase | ||
| 353 | end | ||
| 354 | 428 | ||
| 355 | AGEN: begin | 429 | MEMWAIT: state = `lag(mem_ready) ? FETCH : MEMWAIT; |
| 356 | mem_valid = 1; | ||
| 357 | case (opcode) | ||
| 358 | 'o0, 'o1, 'o2: mem_write = 0; | ||
| 359 | endcase | ||
| 360 | mem_address = address; | ||
| 361 | state = `lag(mem_ready) ? EXEC : AGEN; | ||
| 362 | end | ||
| 363 | 430 | ||
| 364 | EXEC: begin | 431 | HALT: begin |
| 365 | automatic bit stall = 0; | 432 | $display("\nhalt state reached"); |
| 366 | if (`lag(mem_ready)) begin | 433 | $finish; |
| 367 | mem_valid = 0; | ||
| 368 | mem_write = 0; | ||
| 369 | end else if (mem_valid) begin | ||
| 370 | stall = 1; | ||
| 371 | end | 434 | end |
| 372 | case (opcode) | 435 | endcase |
| 373 | 'o0, 'o1, 'o2: if (! `lag(mem_read_valid)) stall = 1; | ||
| 374 | endcase | ||
| 375 | if (! stall) begin | ||
| 376 | state = FETCH; | ||
| 377 | case (opcode) | ||
| 378 | 'o0: begin led_memdata = `lag(mem_read_data); acc &= `lag(mem_read_data); end | ||
| 379 | 'o1: begin led_memdata = `lag(mem_read_data); {link, acc} += {1'b0, `lag(mem_read_data)}; end | ||
| 380 | 'o2: begin | ||
| 381 | mem_valid = 1; | ||
| 382 | mem_address = address; | ||
| 383 | mem_write = 1; | ||
| 384 | mem_write_data = `lag(mem_read_data) + 1; | ||
| 385 | led_memdata = mem_write_data; | ||
| 386 | if (mem_write_data == 0) ++pc; | ||
| 387 | state = MEMWAIT; | ||
| 388 | end | ||
| 389 | 'o3: begin | ||
| 390 | mem_valid = 1; | ||
| 391 | mem_address = address; | ||
| 392 | mem_write = 1; | ||
| 393 | mem_write_data = acc; | ||
| 394 | led_memdata = mem_write_data; | ||
| 395 | acc = 0; | ||
| 396 | state = MEMWAIT; | ||
| 397 | end | ||
| 398 | 'o4: begin | ||
| 399 | mem_valid = 1; | ||
| 400 | mem_address = address; | ||
| 401 | mem_write = 1; | ||
| 402 | mem_write_data = pc[DATA_BITS-1:0]; | ||
| 403 | led_memdata = mem_write_data; | ||
| 404 | pc = address + 1; | ||
| 405 | state = MEMWAIT; | ||
| 406 | end | ||
| 407 | 'o5: pc = address; | ||
| 408 | endcase | ||
| 409 | end | ||
| 410 | end | ||
| 411 | 436 | ||
| 412 | MEMWAIT: state = `lag(mem_ready) ? FETCH : MEMWAIT; | 437 | if (switch_sing_step) |
| 438 | run = 0; | ||
| 413 | 439 | ||
| 414 | HALT: begin | 440 | if (state == FETCH && switch_sing_inst) |
| 415 | $display("\nhalt state reached"); | 441 | run = 0; |
| 416 | $finish; | ||
| 417 | end | ||
| 418 | endcase | ||
| 419 | 442 | ||
| 420 | rx_ready = !kbd_valid; | 443 | rx_ready = !kbd_valid; |
| 444 | end | ||
| 421 | end | 445 | end |
| 422 | end | 446 | end |
| 423 | 447 | ||
| @@ -114,6 +114,9 @@ core cpu | |||
| 114 | , .reset(reset) | 114 | , .reset(reset) |
| 115 | 115 | ||
| 116 | , .switch_cont(switch_cont) | 116 | , .switch_cont(switch_cont) |
| 117 | , .switch_stop(switch_stop) | ||
| 118 | , .switch_sing_step(switch_sing_step) | ||
| 119 | , .switch_sing_inst(switch_sing_inst) | ||
| 117 | 120 | ||
| 118 | , .led_pc(led_pc) | 121 | , .led_pc(led_pc) |
| 119 | , .led_memaddr(led_memaddr) | 122 | , .led_memaddr(led_memaddr) |
