├── .vscode └── launch.json ├── 5bitcounter ├── counter.v └── counter_test.v ├── README.md ├── alu ├── alu.v ├── alu.v.bak ├── alu_test.v ├── alu_test.v.bak └── work │ ├── @_opt │ ├── _lib.qdb │ ├── _lib1_0.qdb │ ├── _lib1_0.qpg │ ├── _lib1_0.qtl │ ├── _lib2_0.qdb │ ├── _lib2_0.qpg │ ├── _lib2_0.qtl │ ├── _lib3_0.qdb │ ├── _lib3_0.qpg │ ├── _lib3_0.qtl │ ├── _lib4_0.qpg │ ├── _lib4_0.qtl │ ├── _lib5_0.qdb │ ├── _lib5_0.qpg │ └── _lib5_0.qtl │ ├── @_opt1 │ ├── _lib.qdb │ ├── _lib1_0.qdb │ ├── _lib1_0.qpg │ ├── _lib1_0.qtl │ ├── _lib2_0.qdb │ ├── _lib2_0.qpg │ ├── _lib2_0.qtl │ ├── _lib3_0.qdb │ ├── _lib3_0.qpg │ ├── _lib3_0.qtl │ ├── _lib4_0.qdb │ ├── _lib4_0.qpg │ └── _lib4_0.qtl │ ├── _info │ ├── _lib.qdb │ ├── _lib1_0.qdb │ ├── _lib1_0.qpg │ ├── _lib1_0.qtl │ └── _vmake ├── cputest.md ├── memory ├── mem.v └── mem_test.v └── register ├── clock.v ├── dffr.v ├── mux.v ├── register.v └── register_test.v /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "(lldb) 启动", 9 | "type": "cppdbg", 10 | "request": "launch", 11 | "program": "输入程序名称,例如 ${workspaceFolder}/a.out", 12 | "args": [], 13 | "stopAtEntry": false, 14 | "cwd": "${workspaceFolder}", 15 | "environment": [], 16 | "externalConsole": false, 17 | "MIMode": "lldb" 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /5bitcounter/counter.v: -------------------------------------------------------------------------------- 1 | 2 | //5-bit counter 3 | `timescale 1 ns / 100 ps 4 | module counter ( cnt, clk, data, rst_, load ) ; 5 | 6 | output [4:0] cnt ; 7 | input [4:0] data ; 8 | input clk ; 9 | input rst_ ; 10 | input load ; 11 | reg [4:0] cnt ; 12 | 13 | always @ ( posedge clk or negedge rst_ ) 14 | if ( !rst_ ) 15 | #1.2 cnt <= 0 ; 16 | else 17 | if ( load ) 18 | cnt <= #3 data ; 19 | else 20 | cnt <= #4 cnt + 1 ; 21 | 22 | endmodule -------------------------------------------------------------------------------- /5bitcounter/counter_test.v: -------------------------------------------------------------------------------- 1 | `timescale 1 ns / 1 ns 2 | 3 | module counter_test ; 4 | 5 | wire [4:0] cnt ; 6 | reg [4:0] data ; 7 | reg rst_ ; 8 | reg load ; 9 | reg clk ; 10 | 11 | counter c1 12 | ( 13 | .cnt (cnt ), 14 | .clk (clk ), 15 | .data (data), 16 | .rst_ (rst_ ), 17 | .load (load) 18 | ); 19 | 20 | initial begin 21 | clk= 0 ; 22 | forever begin 23 | #10 clk = 1'b1 ; 24 | #10 clk = 1'b0 ; 25 | end 26 | end 27 | 28 | initial 29 | begin 30 | $timeformat ( -9, 1, "ns ", 9 ) ; 31 | $monitor("time = %t, data = %h, clk = %b, rst_ = %b, load = %b, cnt = %b", $stime, data, clk, rst_, load, cnt); 32 | $dumpvars(2,counter_test); 33 | end 34 | 35 | task expect; 36 | input [4:0] expects ; 37 | if ( cnt !== expects ) begin 38 | $display ( "At time %t cnt is %b and should be %b", $time, cnt, expects ) ; 39 | $display ( "TEST FAILED" ) ; 40 | $finish ; 41 | end 42 | endtask 43 | 44 | initial 45 | begin // SYNCHRONIZE INTERFACE TO INACTIVE CLOCK EDGE 46 | @(negedge clk) 47 | 48 | // RESET 49 | {rst_, load, data} = 7'b0_X_XXXXX;@(negedge clk) expect(5'h00); 50 | 51 | // LOAD 1D 52 | {rst_, load, data} = 7'b1_1_11101; @(negedge clk) expect(5'h1D); 53 | 54 | // COUNT +5 55 | {rst_, load, data} = 7'b1_0_11101; 56 | repeat(5) @(negedge clk); 57 | expect(5'h02); 58 | 59 | // LOAD 1F 60 | {rst_, load, data} = 7'b1_1_11111; @(negedge clk) expect(5'h1F); 61 | 62 | // RESET 63 | {rst_, load, data} = 7'b0_X_XXXXX; @(negedge clk) expect(5'h00); 64 | $display ( "TEST PASSED" ) ; 65 | $finish ; 66 | 67 | end 68 | 69 | endmodule -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 8bit-RISC-CPU 2 | 用verilog设计8位cpu 3 | 整个CPU结构图: 4 | ![image text](https://github.com/1Allison/img-folder/raw/master/image-20200407171216592.png) 5 | # cpu的工作原理 6 | ## 1. 存储器 7 | #### 功能:用来存储指令系统中的指令。 8 | 所有指令按地址顺序存放在存储器中。指令地址位是4位,cpu是八位,所以存储器是32*8bit。 9 | data是一个双向数据总线。 10 | 当read=1,data从存储器读到总线上。当write在上升沿时,将data从总线写入存储器中。 11 | ```verliog 12 | /*************** * 32X8 MEMORY * ***************/ 13 | 14 | `timescale 1 ns / 1 ns 15 | 16 | module mem ( data, addr, read, write ) ; 17 | inout [7:0] data ; 18 | input [4:0] addr ; 19 | input read ; 20 | input write ; 21 | 22 | reg [7:0] memory [0:31] ; 23 | assign data=(read)?memory[addr]:8'hZ; 24 | 25 | always@(posedge write) 26 | begin 27 | memory[addr]<=data[7:0]; 28 | end 29 | 30 | endmodule 31 | ``` 32 | ## 2.程序计数器 33 | #### 功能:作为状态单元存放想要执行的指令的地址。计数指令的顺序号。 34 | **上边沿有效的异步复位计数器** 35 | 每次cpu重新启动时,从存储器的零地址开始读取指令并且执行。执行完一条指令后,pc_addr增加2,指向下一条指令。若执行的是转移语句,id_pc为1,将该地址装入计数器中。 36 | ``` 37 | //5-bit counter 38 | `timescale 1 ns / 100 ps 39 | module counter ( cnt, clk, data, rst_, load ) ; 40 | 41 | output [4:0] cnt ; 42 | input [4:0] data ; 43 | input clk ; 44 | input rst_ ; 45 | input load ; 46 | reg [4:0] cnt ; 47 | 48 | always @ ( posedge clk or negedge rst_ ) 49 | if ( !rst_ ) 50 | #1.2 cnt <= 0 ; 51 | else 52 | if ( load ) 53 | cnt <= #3 data ; 54 | else 55 | cnt <= #4 cnt + 1 ; 56 | 57 | endmodule 58 | ``` 59 | 60 | #### 寻址方式: 61 | ##### 指令寻址 62 | 1. 顺序寻址 63 | 2. 跳跃寻址 下一条指令的地址码不由计数器给出,在本条指令中指出。 64 | 即指令的内容为 :JMP3。 65 | ##### 操作数寻址 66 | 1. 立即寻址方式 地址字段中直接给操作数(立即数)。 67 | 2. 直接寻址方式 地址字段中直接给操作数在存储器中的地址。 68 | 3. 间接寻址方式 地址字段中直接给操作数的地址在存储器中的地址,从操作数的地址找到操作数。 69 | 4. 寄存器寻址方式 地址字段中直接给寄存器的编号 70 | 4.1 直接 71 | 4.2 间接 72 | 5. 基址寻址 基址寄存器内容+指令中形式地址 得到有效地址 73 | 6. 变址寻址 指令中形式地址为基准,变址寄存器中内容为修改量。 74 | 7. 相对寻址 计数器内容+指令中地址形式 75 | 76 | 在本设计的8位cpu中,采用直接寻址方式 77 | 78 | 79 | ## 3.指令寄存器 80 | #### 功能 存放当前正在执行的指令 81 | 从存储器中经过数据总线把即将执行的指令读入寄存器中。 82 | ``` 83 | /****************** * 8-bit REGISTER * ******************/ 84 | 85 | `timescale 1 ns / 1 ns 86 | 87 | module register ( out, data, load, clk, rst_ ) ; 88 | 89 | output [7:0] out ; 90 | input [7:0] data ; 91 | input load ; 92 | input clk ; 93 | input rst_ ; 94 | 95 | wire [7:0] n1, n2 ; 96 | 97 | mux mux7 98 | (.out(n1[7]), 99 | .sel(load), 100 | .b(data[7]), 101 | .a(out[7]) 102 | ); 103 | dffr dffr7 104 | (.q(out[7]), 105 | .d(n1[7]), 106 | .clk(clk), 107 | .rst_(rst_) 108 | ); 109 | 110 | mux mux6 111 | (.out(n1[6]), 112 | .sel(load), 113 | .b(data[6]), 114 | .a(out[6]) 115 | ); 116 | dffr dffr6 117 | (.q(out[6]), 118 | .d(n1[6]), 119 | .clk(clk), 120 | .rst_(rst_) 121 | ); 122 | 123 | mux mux5 124 | (.out(n1[5]), 125 | .sel(load), 126 | .b(data[5]), 127 | .a(out[5]) 128 | ); 129 | dffr dffr5 130 | (.q(out[5]), 131 | .d(n1[5]), 132 | .clk(clk), 133 | .rst_(rst_) 134 | ); 135 | 136 | mux mux4 137 | (.out(n1[4]), 138 | .sel(load), 139 | .b(data[4]), 140 | .a(out[4]) 141 | ); 142 | dffr dffr4 143 | (.q(out[4]), 144 | .d(n1[4]), 145 | .clk(clk), 146 | .rst_(rst_) 147 | ); 148 | 149 | mux mux3 150 | (.out(n1[3]), 151 | .sel(load), 152 | .b(data[3]), 153 | .a(out[3]) 154 | ); 155 | dffr dffr3 156 | (.q(out[3]), 157 | .d(n1[3]), 158 | .clk(clk), 159 | .rst_(rst_) 160 | ); 161 | 162 | mux mux2 163 | (.out(n1[2]), 164 | .sel(load), 165 | .b(data[2]), 166 | .a(out[2]) 167 | ); 168 | dffr dffr2 169 | (.q(out[2]), 170 | .d(n1[2]), 171 | .clk(clk), 172 | .rst_(rst_) 173 | ); 174 | 175 | mux mux1 176 | (.out(n1[1]), 177 | .sel(load), 178 | .b(data[1]), 179 | .a(out[1]) 180 | ); 181 | dffr dffr1 182 | (.q(out[1]), 183 | .d(n1[1]), 184 | .clk(clk), 185 | .rst_(rst_) 186 | ); 187 | 188 | mux mux0 189 | (.out(n1[0]), 190 | .sel(load), 191 | .b(data[0]), 192 | .a(out[0]) 193 | ); 194 | dffr dffr0 195 | (.q(out[0]), 196 | .d(n1[0]), 197 | .clk(clk), 198 | .rst_(rst_) 199 | ); 200 | 201 | endmodule 202 | ``` 203 | ## 4. 地址多路选择器 204 | 指令执行的情况有两种,需要进行选择。故设计一个二选一开关。 205 | ``` 206 | module scale_mux (out, sel, b, a); 207 | parameter size = 8; 208 | output [size-1:0] out; 209 | input [size-1:0] b, a; 210 | input sel; 211 | assign out = (!sel) ? a : 212 | (sel) ? b : 213 | {size{1'bx}} ; 214 | endmodule 215 | 216 | ``` 217 | 218 | ## 5. 算术逻辑单元 219 | 根据指令的操作码opcode来判断下一步执行什么操作。对数据data和accum(累加器中数据)进行逻辑运算。 220 | 221 | ``` 222 | `timescale 1ns/100ps 223 | module alu(out,zero,opcode,data,accum); 224 | input [7:0] data,accum; 225 | input [2:0] opcode; 226 | output zero; 227 | output [7:0] out; 228 | reg [7:0] out; // 229 | reg zero; 230 | 231 | parameter PASS0 = 3'b000, 232 | PASS1 = 3'b001, 233 | ADD = 3'b010, 234 | AND = 3'b011, 235 | XOR = 3'b100, 236 | PASSD = 3'b101, 237 | PASS6 = 3'b110, 238 | PASS7 = 3'b111; 239 | 240 | always@(opcode or data or accum) 241 | begin 242 | if(accum==8'b00000000) 243 | #1.2 zero=1; 244 | else 245 | #1.2 zero=0; 246 | case(opcode) 247 | PASS0:#3.5 out=accum; 248 | PASS1:#3.5 out=accum; 249 | ADD:#3.5 out=accum+data; 250 | AND:#3.5 out=accum&data; 251 | XOR:#3.5 out=accum^data; 252 | PASSD:#3.5 out=data; 253 | PASS6:#3.5 out=accum; 254 | PASS7:#3.5 out=accum; 255 | default:#3.5 out=8'bx; 256 | endcase 257 | end 258 | 259 | endmodule 260 | ``` 261 | ## 6. 累加器 262 | 寄存器. 263 | 暂时存放ALU的一个操作或者运算结果,比如ADD是 accum=accum+data。 264 | ``` 265 | /****************** 266 | * 8-bit REGISTER * 267 | ******************/ 268 | `timescale 1 ns / 1 ns 269 | module register ( out, data, load, clk, rst_ ) ; 270 | output [7:0] out ; 271 | input [7:0] data ; 272 | input load ; 273 | input clk ; 274 | input rst_ ; 275 | wire [7:0] n1, n2 ; 276 | //???? dffr ? mux ?????? 277 | 278 | dffr d0 279 | ( 280 | .q (out[0]), 281 | .clk (clk), 282 | .rst_(rst_), 283 | .d (n1[0]) 284 | ); 285 | dffr d1 286 | ( 287 | .q (out[1]), 288 | .clk (clk), 289 | .rst_(rst_), 290 | .d (n1[1]) 291 | ); 292 | dffr d2 293 | ( 294 | .q (out[2]), 295 | .clk (clk), 296 | .rst_(rst_), 297 | .d (n1[2]) 298 | ); 299 | dffr d3 300 | ( 301 | .q (out[3]), 302 | .clk (clk), 303 | .rst_(rst_), 304 | .d (n1[3]) 305 | ); 306 | dffr d4 307 | ( 308 | .q (out[4]), 309 | .clk (clk), 310 | .rst_(rst_), 311 | .d (n1[4]) 312 | ); 313 | dffr d5 314 | ( 315 | .q (out[5]), 316 | .clk (clk), 317 | .rst_(rst_), 318 | .d (n1[5]) 319 | ); 320 | dffr d6 321 | ( 322 | .q (out[6]), 323 | .clk (clk), 324 | .rst_(rst_), 325 | .d (n1[6]) 326 | ); 327 | dffr d7 328 | ( 329 | .q (out[7]), 330 | .clk (clk), 331 | .rst_(rst_), 332 | .d (n1[7]) 333 | ); 334 | mux m0 335 | ( 336 | .a (out[0]), 337 | .b (data[0]), 338 | .sel (load), 339 | .out (n1[0]) 340 | ); 341 | mux m1 342 | ( 343 | .a (out[1]), 344 | .b (data[1]), 345 | .sel (load), 346 | .out (n1[1]) 347 | ); 348 | mux m2 349 | ( 350 | .a (out[2]), 351 | .b (data[2]), 352 | .sel (load), 353 | .out (n1[2]) 354 | ); 355 | mux m3 356 | ( 357 | .a (out[3]), 358 | .b (data[3]), 359 | .sel (load), 360 | .out (n1[3]) 361 | ); 362 | mux m4 363 | ( 364 | .a (out[4]), 365 | .b (data[4]), 366 | .sel (load), 367 | .out (n1[4]) 368 | ); 369 | mux m5 370 | ( 371 | .a (out[5]), 372 | .b (data[5]), 373 | .sel (load), 374 | .out (n1[5]) 375 | ); 376 | mux m6 377 | ( 378 | .a (out[6]), 379 | .b (data[6]), 380 | .sel (load), 381 | .out (n1[6]) 382 | ); 383 | mux m7 384 | ( 385 | .a (out[7]), 386 | .b (data[7]), 387 | .sel (load), 388 | .out (n1[7]) 389 | ); 390 | 391 | 392 | endmodule 393 | ``` 394 | ## 7.状态控制器 395 | 396 | ![image text](https://github.com/1Allison/img-folder/raw/master/image-20200407162138106.png) 397 | 398 | 状态控制器是一个控制单元,通过控制何时停止或启动某些部件,何时读指令等。 399 | 400 | 它在8个周期内完成指令的获取和执行。前四个时钟周期为从存储器中取数据,后四个周期用来发出不同的控制信号。 401 | 402 | **读取数据** 403 | 404 | 第一个时钟周期: 405 | sel=1,存储器此时收到了一个mux给的地址pc_addr。 406 | 407 | 第二个时钟周期: 408 | sel=1,rd=1,存储器read=1,按照pc_addr的地址从存储器中读出数据到数据总线data上 409 | 410 | 第三个时钟周期与第四个时钟周期相同(由于8位RISC_CPU读指令需要两个时钟周期):sel=1,rd=1,id_ir=1,指令寄存器开始工作,读取data数据。data为8位数据,前3位是操作数,后五位是地址。 411 | 412 | **处理数据** 413 | 414 | 第五个时钟周期: 415 | inc_pc=1,时钟信号。计数器开始工作。 416 | 417 | 第六个时钟周期: 418 | rd=aluop(一种控制信号),执行ADD,AND,XOR,LDA时,aluop=1,read为1,需要从存储器中读取数据;当执行HLT、 SKZ、STO、JMP时,aluop=0,不需要从存储器中读数据。 419 | 420 | 第七个时钟周期: 421 | 1. 若aluop=1,算术逻辑 422 | 2. 若SKZ&zero=1, 由于SKR操作是 skip if zero true,故需要判断ALU的zero标志是否为1,若zero为1,跳转到下一个语句。 423 | 3. 若JMP=1,PC地址为目标地址 424 | 425 | 第八个时钟周期: 426 | 1. 若aluop=1,则rd=1,data_e=0,ld_ac=1,执行LDA指令,把数据写入累加器中。 427 | 2. 若操作为SKZ,PC地址自增1。 428 | 3. 若操作为JMP,PC地址变成目标地址。 429 | 4. 若操作是STO,则将累加器中的数据写到地址中。 430 | 431 | ## 8.cpu集成设计 432 | 设计顶层模块将cpu的各个模块功能进行实例化。 433 | ``` 434 | /******* 435 | * CPU * 436 | *******/ 437 | `timescale 1 ns/1 ns 438 | module cpu(rst_); 439 | 440 | input rst_; 441 | wire [7:0] data; 442 | wire [7:0] alu_out; 443 | wire [7:0] ir_out; 444 | wire [7:0] ac_out; 445 | wire [4:0] pc_addr; 446 | wire [4:0] ir_addr; 447 | wire [4:0] addr; 448 | wire [2:0] opcode; 449 | 450 | assign opcode=ir_out[7:5]; 451 | assign ir_addr=ir_out[4:0]; 452 | 453 | control ctl1 454 | ( 455 | .rd(rd), 456 | .wr(wr), 457 | .ld_ir(ld_ir), 458 | .ld_ac(ld_ac), 459 | .ld_pc(ld_pc), 460 | .inc_pc(inc_pc), 461 | .halt(halt), 462 | .data_e(data_e), 463 | .sel(sel), 464 | .opcode(opcode), 465 | .zero(zero), 466 | .clk(clock), 467 | .rst_(rst_) 468 | ); 469 | 470 | alu alu1 471 | ( 472 | .out(alu_out), 473 | .zero(zero), 474 | .opcode(opcode), 475 | .data(data), 476 | .accum(ac_out) 477 | ); 478 | 479 | register ac 480 | ( 481 | .out(ac_out), 482 | .data(alu_out), 483 | .load(ld_ac), 484 | .clk(clock), 485 | .rst_(rst_) 486 | ); 487 | 488 | register ir 489 | ( 490 | .out(ir_out), 491 | .data(data), 492 | .load(ld_ir), 493 | .clk(clock), 494 | .rst_(rst_) 495 | ); 496 | 497 | scale_mux #5 smx 498 | ( 499 | .out(addr), 500 | .sel(sel), 501 | .b(pc_addr), 502 | .a(ir_addr) 503 | ); 504 | 505 | mem mem1 506 | ( 507 | .data(data), 508 | .addr(addr), 509 | .read(rd), 510 | .write(wr) 511 | ); 512 | 513 | counter pc 514 | ( 515 | .cnt(pc_addr), 516 | .data(ir_addr), 517 | .load(ld_pc), 518 | .clk(inc_pc), 519 | .rst_(rst_) 520 | ); 521 | 522 | clkgen clk 523 | ( 524 | .clk(clock) 525 | ); 526 | 527 | assign data=(data_e)?alu_out:8'bz; 528 | endmodule 529 | 530 | ``` 531 | 532 | 533 | -------------------------------------------------------------------------------- /alu/alu.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module alu(out,zero,opcode,data,accum); 3 | input [7:0] data,accum; 4 | input [2:0] opcode; 5 | output zero; 6 | output [7:0] out; 7 | reg [7:0] out; // 8 | reg zero; 9 | 10 | parameter PASS0 = 3'b000, 11 | PASS1 = 3'b001, 12 | ADD = 3'b010, 13 | AND = 3'b011, 14 | XOR = 3'b100, 15 | PASSD = 3'b101, 16 | PASS6 = 3'b110, 17 | PASS7 = 3'b111; 18 | 19 | // ???????????? 20 | always@(opcode or data or accum) 21 | begin 22 | if(accum==8'b00000000) 23 | #1.2 zero=1; 24 | else 25 | #1.2 zero=0; 26 | case(opcode) 27 | PASS0:#3.5 out=accum; 28 | PASS1:#3.5 out=accum; 29 | ADD:#3.5 out=accum+data; 30 | AND:#3.5 out=accum&data; 31 | XOR:#3.5 out=accum^data; 32 | PASSD:#3.5 out=data; 33 | PASS6:#3.5 out=accum; 34 | PASS7:#3.5 out=accum; 35 | default:#3.5 out=8'bx; 36 | endcase 37 | end 38 | 39 | endmodule 40 | -------------------------------------------------------------------------------- /alu/alu.v.bak: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module alu(out,zero,opcode,data,accum); 3 | input [7:0] data,accum; 4 | input [2:0] opcode; 5 | output zero; 6 | output [7:0] out; 7 | reg [7:0] out; // 8 | reg zero; 9 | 10 | parameter PASS0 = 3'b000, 11 | PASS1 = 3'b001, 12 | ADD = 3'b010, 13 | AND = 3'b011, 14 | XOR = 3'b100, 15 | PASSD = 3'b101, 16 | PASS6 = 3'b110, 17 | PASS7 = 3'b111; 18 | 19 | // ???????????? 20 | always@(opcode or data or accum) 21 | begin 22 | if(accum==8'b00000000) 23 | #1.2 zero=1; 24 | else 25 | #1.2 zero=0; 26 | case(opcode) 27 | PASS0:#3.5 out=accum; 28 | PASS1:#3.5 out=accum; 29 | ADD:#3.5 out=accum+data; 30 | AND:#3.5 out=accum&data; 31 | XOR:#3.5 out=accum^data; 32 | PASSD:#3.5 out=data; 33 | PASS6:#3.5 out=accum; 34 | PASS7:#3.5 out=accum; 35 | default:#3.5 out=8'bx; 36 | endcase 37 | end 38 | 39 | endmodule 40 | -------------------------------------------------------------------------------- /alu/alu_test.v: -------------------------------------------------------------------------------- 1 | `timescale 1 ns / 1 ns 2 | 3 | // Define the delay from stimulus to response check 4 | `define DELAY 20 5 | module alu_test ; 6 | 7 | wire [7:0] out ; 8 | reg [7:0] data ; 9 | reg [7:0] accum ; 10 | reg [2:0] opcode ; 11 | integer i ; 12 | 13 | 14 | // Define opcodes 15 | parameter PASS0 = 3'b000, 16 | PASS1 = 3'b001, 17 | ADD = 3'b010, 18 | AND = 3'b011, 19 | XOR = 3'b100, 20 | PASSD = 3'b101, 21 | PASS6 = 3'b110, 22 | PASS7 = 3'b111; // Instantiate the ALU. // Use explicit port mapping. 23 | 24 | alu alu1 25 | ( .out (out ), 26 | .zero (zero ), 27 | .opcode (opcode ), 28 | .data (data), 29 | .accum (accum ) ); 30 | // Monitor signals 31 | initial 32 | begin 33 | $display ( "<------------ INPUTS ------------> <-OUTPUTS->" ) ; 34 | $display ( " TIME OPCODE DATA IN ACCUM IN ALU OUT ZERO BIT" ) ; 35 | $display ( "--------- ------ -------- -------- -------- --------" ) ; 36 | $timeformat ( -9, 1, " ns", 9 ) ; 37 | $dumpvars(2,alu_test); 38 | end 39 | // Verify response 40 | task expect ; 41 | input [8:0] expects ; 42 | begin 43 | $display("%t %b %b %b %b %b", $time, opcode, data, accum, out, zero ) ; 44 | if ( {zero,out} !== expects ) 45 | begin 46 | $display ( "At time %t: zero is %b and should be %b, out is %b and should be %b",$time, zero, expects[8], out, expects[7:0] ) ; 47 | $display ( "TEST FAILED" ) ; 48 | $finish ; 49 | end 50 | end 51 | endtask 52 | // Apply stimulus 53 | initial 54 | begin 55 | {opcode,accum,data} = {PASS0,8'h00,8'hFF}; #(`DELAY) expect({1'b1,accum }); 56 | {opcode,accum,data} = {PASS0,8'h55,8'hFF}; #(`DELAY) expect({1'b0,accum }); 57 | {opcode,accum,data} = {PASS1,8'h55,8'hFF}; #(`DELAY) expect({1'b0,accum }); 58 | {opcode,accum,data} = {PASS1,8'hCC,8'hFF}; #(`DELAY) expect({1'b0,accum }); 59 | {opcode,accum,data} = {ADD ,8'h33,8'hAA}; #(`DELAY) expect({1'b0,accum+data}); 60 | {opcode,accum,data} = {AND ,8'h0F,8'h33}; #(`DELAY) expect({1'b0,accum&data}); 61 | {opcode,accum,data} = {XOR ,8'hF0,8'h55}; #(`DELAY) expect({1'b0,accum^data}); 62 | {opcode,accum,data} = {PASSD,8'h00,8'hAA}; #(`DELAY) expect({1'b1, data}); 63 | {opcode,accum,data} = {PASSD,8'h00,8'hCC}; #(`DELAY) expect({1'b1, data}); 64 | {opcode,accum,data} = {PASS6,8'hFF,8'hF0}; #(`DELAY) expect({1'b0,accum }); 65 | {opcode,accum,data} = {PASS7,8'hCC,8'h0F}; #(`DELAY) expect({1'b0,accum }); 66 | $display("TEST PASSED"); 67 | $finish; 68 | end 69 | 70 | endmodule -------------------------------------------------------------------------------- /alu/alu_test.v.bak: -------------------------------------------------------------------------------- 1 | `timescale 1 ns / 1 ns 2 | 3 | // Define the delay from stimulus to response check 4 | `define DELAY 20 5 | module alu_test ; 6 | 7 | wire [7:0] out ; 8 | reg [7:0] data ; 9 | reg [7:0] accum ; 10 | reg [2:0] opcode ; 11 | integer i ; 12 | 13 | 14 | // Define opcodes 15 | parameter PASS0 = 3'b000, 16 | PASS1 = 3'b001, 17 | ADD = 3'b010, 18 | AND = 3'b011, 19 | XOR = 3'b100, 20 | PASSD = 3'b101, 21 | PASS6 = 3'b110, 22 | PASS7 = 3'b111; // Instantiate the ALU. // Use explicit port mapping. 23 | 24 | alu alu1 ( .out (out ), .zero (zero ), .opcode (opcode ), .data (data), .accum (accum ) ); 25 | // Monitor signals 26 | initial 27 | begin 28 | $display ( "<------------ INPUTS ------------> <-OUTPUTS->" ) ; 29 | $display ( " TIME OPCODE DATA IN ACCUM IN ALU OUT ZERO BIT" ) ; 30 | $display ( "--------- ------ -------- -------- -------- --------" ) ; 31 | $timeformat ( -9, 1, " ns", 9 ) ; 32 | $dumpvars(2,alu_test); 33 | end 34 | // Verify response 35 | task expect ; 36 | input [8:0] expects ; 37 | begin 38 | $display("%t %b %b %b %b %b", $time, opcode, data, accum, out, zero ) ; 39 | if ( {zero,out} !== expects ) 40 | begin 41 | $display ( "At time %t: zero is %b and should be %b, out is %b and should be %b",$time, zero, expects[8], out, expects[7:0] ) ; 42 | $display ( "TEST FAILED" ) ; 43 | $finish ; 44 | end 45 | end 46 | endtask 47 | // Apply stimulus 48 | initial 49 | begin 50 | {opcode,accum,data} = {PASS0,8'h00,8'hFF}; #(`DELAY) expect({1'b1,accum }); 51 | {opcode,accum,data} = {PASS0,8'h55,8'hFF}; #(`DELAY) expect({1'b0,accum }); 52 | {opcode,accum,data} = {PASS1,8'h55,8'hFF}; #(`DELAY) expect({1'b0,accum }); 53 | {opcode,accum,data} = {PASS1,8'hCC,8'hFF}; #(`DELAY) expect({1'b0,accum }); 54 | {opcode,accum,data} = {ADD ,8'h33,8'hAA}; #(`DELAY) expect({1'b0,accum+data}); 55 | {opcode,accum,data} = {AND ,8'h0F,8'h33}; #(`DELAY) expect({1'b0,accum&data}); 56 | {opcode,accum,data} = {XOR ,8'hF0,8'h55}; #(`DELAY) expect({1'b0,accum^data}); 57 | {opcode,accum,data} = {PASSD,8'h00,8'hAA}; #(`DELAY) expect({1'b1, data}); 58 | {opcode,accum,data} = {PASSD,8'h00,8'hCC}; #(`DELAY) expect({1'b1, data}); 59 | {opcode,accum,data} = {PASS6,8'hFF,8'hF0}; #(`DELAY) expect({1'b0,accum }); 60 | {opcode,accum,data} = {PASS7,8'hCC,8'h0F}; #(`DELAY) expect({1'b0,accum }); 61 | $display("TEST PASSED"); 62 | $finish; 63 | end 64 | 65 | endmodule -------------------------------------------------------------------------------- /alu/work/@_opt/_lib.qdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt/_lib.qdb -------------------------------------------------------------------------------- /alu/work/@_opt/_lib1_0.qdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt/_lib1_0.qdb -------------------------------------------------------------------------------- /alu/work/@_opt/_lib1_0.qpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt/_lib1_0.qpg -------------------------------------------------------------------------------- /alu/work/@_opt/_lib1_0.qtl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt/_lib1_0.qtl -------------------------------------------------------------------------------- /alu/work/@_opt/_lib2_0.qdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt/_lib2_0.qdb -------------------------------------------------------------------------------- /alu/work/@_opt/_lib2_0.qpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt/_lib2_0.qpg -------------------------------------------------------------------------------- /alu/work/@_opt/_lib2_0.qtl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt/_lib2_0.qtl -------------------------------------------------------------------------------- /alu/work/@_opt/_lib3_0.qdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt/_lib3_0.qdb -------------------------------------------------------------------------------- /alu/work/@_opt/_lib3_0.qpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt/_lib3_0.qpg -------------------------------------------------------------------------------- /alu/work/@_opt/_lib3_0.qtl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt/_lib3_0.qtl -------------------------------------------------------------------------------- /alu/work/@_opt/_lib4_0.qpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt/_lib4_0.qpg -------------------------------------------------------------------------------- /alu/work/@_opt/_lib4_0.qtl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt/_lib4_0.qtl -------------------------------------------------------------------------------- /alu/work/@_opt/_lib5_0.qdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt/_lib5_0.qdb -------------------------------------------------------------------------------- /alu/work/@_opt/_lib5_0.qpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt/_lib5_0.qpg -------------------------------------------------------------------------------- /alu/work/@_opt/_lib5_0.qtl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt/_lib5_0.qtl -------------------------------------------------------------------------------- /alu/work/@_opt1/_lib.qdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt1/_lib.qdb -------------------------------------------------------------------------------- /alu/work/@_opt1/_lib1_0.qdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt1/_lib1_0.qdb -------------------------------------------------------------------------------- /alu/work/@_opt1/_lib1_0.qpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt1/_lib1_0.qpg -------------------------------------------------------------------------------- /alu/work/@_opt1/_lib1_0.qtl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt1/_lib1_0.qtl -------------------------------------------------------------------------------- /alu/work/@_opt1/_lib2_0.qdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt1/_lib2_0.qdb -------------------------------------------------------------------------------- /alu/work/@_opt1/_lib2_0.qpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt1/_lib2_0.qpg -------------------------------------------------------------------------------- /alu/work/@_opt1/_lib2_0.qtl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt1/_lib2_0.qtl -------------------------------------------------------------------------------- /alu/work/@_opt1/_lib3_0.qdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt1/_lib3_0.qdb -------------------------------------------------------------------------------- /alu/work/@_opt1/_lib3_0.qpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt1/_lib3_0.qpg -------------------------------------------------------------------------------- /alu/work/@_opt1/_lib3_0.qtl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt1/_lib3_0.qtl -------------------------------------------------------------------------------- /alu/work/@_opt1/_lib4_0.qdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt1/_lib4_0.qdb -------------------------------------------------------------------------------- /alu/work/@_opt1/_lib4_0.qpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt1/_lib4_0.qpg -------------------------------------------------------------------------------- /alu/work/@_opt1/_lib4_0.qtl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/@_opt1/_lib4_0.qtl -------------------------------------------------------------------------------- /alu/work/_info: -------------------------------------------------------------------------------- 1 | m255 2 | K4 3 | z2 4 | 13 5 | !s112 1.1 6 | !i10d 8192 7 | !i10e 25 8 | !i10f 100 9 | cModel Technology 10 | Z0 dE:/modeltech64_10.7/register 11 | T_opt 12 | !s110 1585225930 13 | VR3klQ0lGcZzLXzQDVZ]II0 14 | Z1 04 8 4 work alu_test fast 0 15 | =1-c0335e14d27f-5e7ca0ca-279-36a0 16 | o-quiet -auto_acc_if_foreign -work work +acc 17 | Z2 tCvgOpt 0 18 | n@_opt 19 | Z3 OL;O;10.7;67 20 | R0 21 | T_opt1 22 | !s110 1585226117 23 | VAP]hJ`RUg5;A^bM1<8mF33 24 | R1 25 | =1-c0335e14d27f-5e7ca185-124-25d4 26 | o-quiet -auto_acc_if_foreign -work work 27 | R2 28 | n@_opt1 29 | R3 30 | valu 31 | Z4 !s110 1585225921 32 | !i10b 1 33 | !s100 dD7PHE2Eb`PIIhWMTDeK60 34 | IdBRA0k[aIN:Li99i86^el2 35 | Z5 VDg1SIo80bB@j0V0VzS_@n1 36 | Z6 dE:/modeltech64_10.7/alu 37 | w1585225675 38 | 8E:/modeltech64_10.7/alu/alu.v 39 | FE:/modeltech64_10.7/alu/alu.v 40 | L0 2 41 | Z7 OL;L;10.7;67 42 | r1 43 | !s85 0 44 | 31 45 | Z8 !s108 1585225921.000000 46 | !s107 E:/modeltech64_10.7/alu/alu.v| 47 | !s90 -reportprogress|300|-work|work|-vopt|-stats=none|E:/modeltech64_10.7/alu/alu.v| 48 | !i113 0 49 | Z9 o-work work -L mtiAvm -L mtiRnm -L mtiOvm -L mtiUvm -L mtiUPF -L infact 50 | R2 51 | valu_test 52 | R4 53 | !i10b 1 54 | !s100 RmW_>fK[n^fQTJ>nbPhkS2 55 | IFem2>[`:AlAlFQRJzJ8lK1 56 | R5 57 | R6 58 | w1585225918 59 | 8E:/modeltech64_10.7/alu/alu_test.v 60 | FE:/modeltech64_10.7/alu/alu_test.v 61 | L0 5 62 | R7 63 | r1 64 | !s85 0 65 | 31 66 | R8 67 | !s107 E:/modeltech64_10.7/alu/alu_test.v| 68 | !s90 -reportprogress|300|-work|work|-vopt|-stats=none|E:/modeltech64_10.7/alu/alu_test.v| 69 | !i113 0 70 | R9 71 | R2 72 | -------------------------------------------------------------------------------- /alu/work/_lib.qdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/_lib.qdb -------------------------------------------------------------------------------- /alu/work/_lib1_0.qdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/_lib1_0.qdb -------------------------------------------------------------------------------- /alu/work/_lib1_0.qpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/_lib1_0.qpg -------------------------------------------------------------------------------- /alu/work/_lib1_0.qtl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/alu/work/_lib1_0.qtl -------------------------------------------------------------------------------- /alu/work/_vmake: -------------------------------------------------------------------------------- 1 | m255 2 | K4 3 | z0 4 | cModel Technology 5 | -------------------------------------------------------------------------------- /cputest.md: -------------------------------------------------------------------------------- 1 | #对cpu功能进行验证 2 | ###测试文件CPUTest1.dat 3 | a. 首先opcode为111,对应操作指令JMP,跳转到地址00011110继续执行。00: fe 4 | 若跳转失败,则指令顺序执行,执行opcode为000,对应操作指令为HLT。 5 | b.跳转成功, 在11110地址处执行111_00011,跳转到00011地址处 1e:e3 6 | c.跳转成功,执行 101_11010,opcode为101,对应操作指令为LDA,将在11010地址处数 据data1放入累加器中。03:ba 7 | d.之后执行opcode为001,对应操作指令为SKZ条件操作指令则判断在00000地址处,若 alu=0,跳过下一条语句。04:20 8 | e.之后执行 101_11011 ,将在11011地址中的数据data2放入累加器中,则判断在00000地址 处,若alu=0,跳过下一条语句。 06:bb 9 | f.执行111_01010,跳转到地址01010处。执行110_11100 ,将累加器中的数据存入地址 11100中。07:20 10 | g.之后顺序执行101_11010,对应操作指令为LDA,将11010地址处数据data1放入累加器 中。08:ea 11 | h.之后顺序执行110_11100,将累加器中的数据存入地址11100中。 0a:dc 12 | i.之后顺序执行001_00000, 将11010地址处数据data1放入累加器中。 0b:ba 13 | j.之后顺序执行110_11100 ,将累加器中的数据存入地址11100中。0c:dc 14 | k.之后顺序执行101_11100 , 将11010地址处数据data1放入累加器中 。0d:bc 15 | l.之后顺序执行 001_00000 ,对应操作指令为SKZ条件操作指令,则判断在00000地址处, 若alu=0,跳过下一条语句 。0e:20 16 | m.顺序执行100_11011,将00100地址中数据与累加器中数据异或。 10:9b 17 | n.顺序执行 001_00000。看xor是否工作。对应操作指令为SKZ,则在00000地址处:若 18 | alu=0,跳过下一条语句。 11:20 19 | o.顺序执行111_10100 。对应操作指令JMP,跳转到地址10100继续执行。12:f4 p.跳转到地址14,执行100_11011。将00100地址中数据与累加器中数据异或。14:9b 20 | q.顺序执行001_00000,对应操作指令为SKZ,则在00000地址处:若alu=0,跳过下一条语 句。 21 | r. 顺序执行000_00000 ,程序结束,进行HLT状态,停机。 另:以上指令若执行不成功则进入HLT状态。 22 | 代码如下: 23 | ``` 24 | //opcode_operand // addr assembly code 25 | //-------------- // ---- -------------------------------------------- 26 | @00 111_11110 // 00 BEGIN: JMP TST_JMP 27 | 000_00000 // 01 HLT //JMP did not work at all 28 | 000_00000 // 02 HLT //JMP did not load PC, it skipped 29 | 101_11010 // 03 JMP_OK: LDA DATA_1 30 | 001_00000 // 04 SKZ 31 | 000_00000 // 05 HLT //SKZ or LDA did not work 32 | 101_11011 // 06 LDA DATA_2 33 | 001_00000 // 07 SKZ 34 | 111_01010 // 08 JMP SKZ_OK 35 | 000_00000 // 09 HLT //SKZ or LDA did not work 36 | 110_11100 // 0A STO TEMP//store non-zero value in TEMP 37 | 101_11010 // 0B LDA DATA_1 38 | 110_11100 // 0C STO TEMP //store zero value in TEMP 39 | 101_11100 // 0D LDA TEMP 40 | 001_00000 // 0E SKZ //check to see if STO worked 41 | 000_00000 // 0F HLT //STO did not work 42 | 100_11011 // 10 XOR DATA_2 43 | 001_00000 // 11 SKZ //check to see if XOR worked 44 | 111_10100 // 12 JMP XOR_OK 45 | 000_00000 // 13 HLT //XOR did not work at all 46 | 100_11011 // 14 XOR_OK: XOR DATA_2 47 | 001_00000 // 15 SKZ 48 | 000_00000 // 16 HLT //XOR did not switch all bits 49 | 000_00000 // 17 END:HLT//CONGRATULATIONS - TEST1 PASSED! 50 | 111_00000 // 18 JMP BEGIN //run test again 51 | @1A 00000000 // 1A DATA_1: //constant 00 52 | 11111111 // 1B DATA_2: //constant FF 53 | 10101010 // 1C TEMP: //variable 54 | @1E 111_00011 // 1E TST_JMP: JMP JMP_OK 55 | 000_00000 // 1F HLT //JMP is broken 56 | ``` 57 | ###测试文件CPUTest2.dat 58 | 59 | a.101_11011 将11011处数据DATA_2送到累加器中 。 00:bb 60 | b.011_11100 顺序执行 将11100地址中存的数据DATA_3与累加器中数据DATA_2进行AND操作,结果放回累加器 01:7c 61 | c.100_11011 将11011地址中存的数据DATA_2与累加器中数据(DATA_2)AND(DATA_3)进行XOR操作,结果放回累加器 02:9b 62 | d.001_00000 验证操作是否正确 03:20 63 | e.010_11010 将11010地址中存的数据DATA_1与累加器中数据ADD操作,结果放回累加器 05:5a 64 | f. 001_00000 验证操作是否正确 06:20 65 | g.111_01001 跳转到地址01001ADD_OK处 07:e9 66 | h.100_11100 将11100地址中存的数据DATA_3与累加器中数据进行XOR操作,结果放回累加器 09:9c 67 | i. 010_11010 将11010地址中存的数据DATA_1与累加器中数据ADD操作,结果放回累加器 0a:5a 68 | j. 110_11101 将累加器中的数据存入地址11101的TEMP中。0b:dd 69 | k.101_11010 将11010处数据DATA_1送到累加器中 。 0c:ba 70 | l. 010_11101 将11011地址中存的数据TEMP与累加器中数据ADD操作,结果放回累加器。0d:5d 71 | g.001_00000 验证操作是否正确 oe:20 72 | k.000_00000 程序结束 73 | 总体功能为计算((((DATA_2)AND(DATA_3)XOR DATA_2)+DATA_1)XOR DATA_3)+DATA_1 74 | 代码如下: 75 | ``` 76 | //opcode_operand // addr assembly code 77 | //-------------- // ---- ------------------------------------------- 78 | @00 101_11011 // 00 BEGIN: LDA DATA_2 79 | 011_11100 // 01 AND DATA_3 80 | 100_11011 // 02 XOR DATA_2 81 | 001_00000 // 03 SKZ 82 | 000_00000 // 04 HLT //AND doesn't work 83 | 010_11010 // 05 ADD DATA_1 84 | 001_00000 // 06 SKZ 85 | 111_01001 // 07 JMP ADD_OK 86 | 000_00000 // 08 HLT //ADD doesn't work 87 | 100_11100 // 09 XOR DATA_3 88 | 010_11010 // 0A ADD DATA_1 //FF plus 1 makes -1 89 | 110_11101 // 0B STO TEMP 90 | 101_11010 // 0C LDA DATA_1 91 | 010_11101 // 0D ADD TEMP //-1 plus 1 should make zero 92 | 001_00000 // 0E SKZ 93 | 000_00000 // 0F HLT //ADD Doesn't work 94 | 000_00000 // 10 END: HLT //CONGRATULATIONS - TEST2 PASSED! 95 | 111_00000 // 11 JMP BEGIN //run test again 96 | @1A 00000001 // 1A DATA_1: //constant 1(hex) 97 | 10101010 // 1B DATA_2: //constant AA(hex) 98 | 11111111 // 1C DATA_3: //constant FF(hex) 99 | 00000000 // 1D TEMP: 100 | ``` 101 | ###测试文件CPUTest3.dat 102 | 总体功能为计算斐波那契数列的之并输出到144 103 | 代码如下: 104 | ``` 105 | //opcode_operand // addr assembly code 106 | //-------------- // ---- -------------------------------------------- 107 | 111_00011 // 00 JMP LOOP //jump to the address of LOOP 108 | @03 101_11011 // 03 LOOP: LDA FN2//load value in FN2 into accum 109 | 110_11100 // 04 STO TEMP //store accumulator in TEMP 110 | 010_11010 // 05 ADD FN1 //add value in FN1 to accumulator 111 | 110_11011 // 06 STO FN2 //store result in FN2 112 | 101_11100 // 07 LDA TEMP //load TEMP into the accumulator 113 | 110_11010 // 08 STO FN1 //store accumulator in FN1 114 | 100_11101 // 09 XOR LIMIT //compare accumulator to LIMIT 115 | 001_00000 // 0A SKZ //if accum = 0, skip to DONE 116 | 111_00011 // 0B JMP LOOP //jump to address of LOOP 117 | 000_00000 // 0C DONE: HLT //end of program 118 | 101_11111 // 0D AGAIN: LDA ONE 119 | 110_11010 // 0E STO FN1 120 | 101_11110 // 0F LDA ZERO 121 | 110_11011 // 10 STO FN2 122 | 111_00011 // 11 JMP LOOP //jump to address of LOOP 123 | @1A 000_00001 // 1A FN1: //variable - stores 1st Fib. No. 124 | 000_00000 // 1B FN2: //variable - stores 2nd Fib. No. 125 | 000_00000 // 1C TEMP: //temporary variable 126 | 100_10000 // 1D LIMIT: //constant 144 - max value 127 | 000_00000 // 1E ZERO: //constant 0 128 | 000_00001 // 1F ONE: //constant 1// 129 | ``` 130 | ##3自行编写功能验证 131 | 仿照CPUTest3.dat中对斐波那契数列的测试,写了对佩尔数列的测试进行验证 Pell数列a1, a2, a3, ...的定义是这样的, 132 | 一组数据为:a1 = 1, a2 = 2, ... ,为:an = 2 * a[n − 1] + a[n - 2] (n > 2) 133 | 代码如下: 134 | ``` 135 | 136 | //opcode_operand // addr assembly code //-------------- // ---- -------------------------------------------- 137 | 111_00011 // 00 @03 101_11010 // 03 138 | JMP LOOP //jump to the address of LOOP LOOP:LDA N1 //load value in N1 into accum STO TEMP //store accumulator in TEMP 139 | 110_11110 010_11011 010_11011 110_11100 101_11011 110_11010 101_11100 110_11011 100_11111 001_00000 111_00011 000_00000 140 | @1A 00000000 141 | 00000001 142 | 00000000 143 | 00000000 144 | 10101001 145 | // 04 // 05 // 06 // 07 // 08 // 09 // 0A // 0B // 0C // 0D // 0E // 0F 146 | ADD N2 ADD N2 STO N3 LDA N2 STO N1 LDA N3 STO N2 147 | JMP LOOP //jump to the address of LOOP DONE:HLT //end of program 148 | //add value in N2 to accumulator //store accumulator in N3 149 | //store accumulator in N2 150 | //store accumulator in N2 151 | XOR LIMIT //compare accumulator to LIMIT SKZ //if accum = 0, skip to DONE 152 | // 1A N1: //variable - stores 1st Fib. No. // 1B N2: //variable - stores 2nd Fib. No. // 1C N3: //variable - current value 153 | // 1D TEMP: //temporary variable 154 | // 1E LIMIT: //constant 169 - max value 155 | ``` -------------------------------------------------------------------------------- /memory/mem.v: -------------------------------------------------------------------------------- 1 | 2 | /*************** * 32X8 MEMORY * ***************/ 3 | 4 | `timescale 1 ns / 1 ns 5 | 6 | module mem ( data, addr, read, write ) ; 7 | inout [7:0] data ; 8 | input [4:0] addr ; 9 | input read ; 10 | input write ; 11 | 12 | reg [7:0] memory [0:31] ; 13 | assign data=(read)?memory[addr]:8'hZ; 14 | 15 | always@(posedge write) 16 | begin 17 | memory[addr]<=data[7:0]; 18 | end 19 | 20 | endmodule -------------------------------------------------------------------------------- /memory/mem_test.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1Allison/8bit-RISC-CPU/e0cfb44f30fd467d5c484d167755a23a73444b08/memory/mem_test.v -------------------------------------------------------------------------------- /register/clock.v: -------------------------------------------------------------------------------- 1 | 2 | `timescale 1 ns/1 ns 3 | module clock(clk); 4 | reg clk; 5 | output clk; 6 | initial begin 7 | clk =0; 8 | forever begin 9 | #10 clk=1'b1; 10 | #10 clk=1'b0; 11 | end 12 | end 13 | end module 14 | -------------------------------------------------------------------------------- /register/dffr.v: -------------------------------------------------------------------------------- 1 | `timescale 1 ns / 1 ns 2 | 3 | `celldefine 4 | 5 | module dffr ( q, q_, d, clk, rst_ ) ; 6 | output q ; 7 | output q_ ; 8 | input d ; 9 | input clk ; 10 | input rst_ ; 11 | nand n1 ( de, dl, qe ) ; 12 | nand n2 ( qe, clk, de, rst_ ) ; 13 | nand n3 ( dl, d, dl_, rst_ ) ; 14 | nand n4 ( dl_, dl, clk, qe ) ; 15 | nand n5 ( q, qe, q_ ) ; 16 | nand n6 ( q_, dl_, q, rst_ ) ; 17 | 18 | endmodule 19 | `endcelldefine 20 | -------------------------------------------------------------------------------- /register/mux.v: -------------------------------------------------------------------------------- 1 | `timescale 1 ns / 1 ns 2 | 3 | `celldefine 4 | 5 | module mux ( out, sel, b, a ) ; 6 | 7 | output out ; 8 | input sel ; 9 | input b ; 10 | input a ; 11 | not ( sel_ , sel ) ; 12 | and ( selb , sel , b ) ; 13 | and ( sela , sel_ , a ) ; 14 | or ( out , selb , sela ) ; 15 | endmodule 16 | `endcelldefine 17 | 18 | -------------------------------------------------------------------------------- /register/register.v: -------------------------------------------------------------------------------- 1 | /****************** * 8-bit REGISTER * ******************/ 2 | 3 | `timescale 1 ns / 1 ns 4 | 5 | module register ( out, data, load, clk, rst_ ) ; 6 | 7 | output [7:0] out ; 8 | input [7:0] data ; 9 | input load ; 10 | input clk ; 11 | input rst_ ; 12 | 13 | wire [7:0] n1, n2 ; 14 | 15 | mux mux7 16 | (.out(n1[7]), 17 | .sel(load), 18 | .b(data[7]), 19 | .a(out[7]) 20 | ); 21 | dffr dffr7 22 | (.q(out[7]), 23 | .d(n1[7]), 24 | .clk(clk), 25 | .rst_(rst_) 26 | ); 27 | 28 | mux mux6 29 | (.out(n1[6]), 30 | .sel(load), 31 | .b(data[6]), 32 | .a(out[6]) 33 | ); 34 | dffr dffr6 35 | (.q(out[6]), 36 | .d(n1[6]), 37 | .clk(clk), 38 | .rst_(rst_) 39 | ); 40 | 41 | mux mux5 42 | (.out(n1[5]), 43 | .sel(load), 44 | .b(data[5]), 45 | .a(out[5]) 46 | ); 47 | dffr dffr5 48 | (.q(out[5]), 49 | .d(n1[5]), 50 | .clk(clk), 51 | .rst_(rst_) 52 | ); 53 | 54 | mux mux4 55 | (.out(n1[4]), 56 | .sel(load), 57 | .b(data[4]), 58 | .a(out[4]) 59 | ); 60 | dffr dffr4 61 | (.q(out[4]), 62 | .d(n1[4]), 63 | .clk(clk), 64 | .rst_(rst_) 65 | ); 66 | 67 | mux mux3 68 | (.out(n1[3]), 69 | .sel(load), 70 | .b(data[3]), 71 | .a(out[3]) 72 | ); 73 | dffr dffr3 74 | (.q(out[3]), 75 | .d(n1[3]), 76 | .clk(clk), 77 | .rst_(rst_) 78 | ); 79 | 80 | mux mux2 81 | (.out(n1[2]), 82 | .sel(load), 83 | .b(data[2]), 84 | .a(out[2]) 85 | ); 86 | dffr dffr2 87 | (.q(out[2]), 88 | .d(n1[2]), 89 | .clk(clk), 90 | .rst_(rst_) 91 | ); 92 | 93 | mux mux1 94 | (.out(n1[1]), 95 | .sel(load), 96 | .b(data[1]), 97 | .a(out[1]) 98 | ); 99 | dffr dffr1 100 | (.q(out[1]), 101 | .d(n1[1]), 102 | .clk(clk), 103 | .rst_(rst_) 104 | ); 105 | 106 | mux mux0 107 | (.out(n1[0]), 108 | .sel(load), 109 | .b(data[0]), 110 | .a(out[0]) 111 | ); 112 | dffr dffr0 113 | (.q(out[0]), 114 | .d(n1[0]), 115 | .clk(clk), 116 | .rst_(rst_) 117 | ); 118 | 119 | endmodule -------------------------------------------------------------------------------- /register/register_test.v: -------------------------------------------------------------------------------- 1 | /********************************* * TEST BENCH FOR 8-BIT REGISTER * *********************************/ 2 | `timescale 1 ns / 1 ns 3 | module register_test; 4 | 5 | wire [7:0] out ; 6 | reg [7:0] data ; 7 | reg load ; 8 | reg rst_ ; 9 | reg clk; 10 | // ???????? 11 | // Instantiate register 12 | register c1 13 | (.out(out), 14 | .data(data), 15 | .load(load), 16 | .rst_(rst_), 17 | .clk(clk)); 18 | 19 | 20 | // Instantiate clock 21 | initial begin 22 | clk =0; 23 | forever begin 24 | #10 clk=1'b1; 25 | #10 clk=1'b0; 26 | end 27 | end 28 | 29 | // Monitor signals 30 | 31 | initial 32 | begin 33 | $timeformat(-9,1,"ns",9); 34 | $monitor("time=%t, clk=%b, data=%h, load=%b, out=%h",$stime, clk, data, load, out); 35 | $dumpvars(2,register_test); 36 | end 37 | 38 | // Apply stimulus 39 | 40 | initial 41 | begin 42 | // INSERT STIMULUS HERE 43 | /*To prevent clock/data races,ensure that you don?t transition the stimulus on the active(positive)edge of the clock */ 44 | 45 | @ ( negedge clk ) // Initialize signals 46 | rst_ = 0 ; 47 | data = 0 ; 48 | load = 0 ; 49 | 50 | @ ( negedge clk ) // Release reset 51 | rst_ = 1 ; 52 | 53 | @ ( negedge clk ) // Load hex 55 54 | data = 'h55 ; 55 | load = 1 ; 56 | 57 | @ ( negedge clk ) // Load hex AA 58 | data = 'hAA ; 59 | load = 1 ; 60 | 61 | @ ( negedge clk ) // Disable load but register 62 | data = 'hCC ; 63 | load = 0 ; 64 | 65 | @ ( negedge clk ) // Terminate simulation 66 | $finish ; 67 | end 68 | 69 | endmodule 70 | --------------------------------------------------------------------------------