diff options
| author | kryptoish <krish_thakur7@icloud.com> | 2024-12-07 22:12:43 -0800 |
|---|---|---|
| committer | kryptoish <krish_thakur7@icloud.com> | 2024-12-07 22:12:43 -0800 |
| commit | f9d92b31e4bea3037c75f7c7a508c1be09811fd0 (patch) | |
| tree | 5cd7160603f0841c0661e5c50fca5e3c28b96af4 | |
| parent | added files (diff) | |
Final Working Version
| -rw-r--r-- | .editorconfig | 9 | ||||
| -rw-r--r-- | README.md | 42 | ||||
| -rw-r--r-- | alu.sv | 21 | ||||
| -rw-r--r-- | cpu.sv | 150 | ||||
| -rw-r--r-- | data.txt | 256 | ||||
| -rw-r--r-- | datapath.sv | 48 | ||||
| -rw-r--r-- | images/rankings.png | bin | 0 -> 146114 bytes | |||
| -rw-r--r-- | lab7bonus_autograder_check.sv | 71 | ||||
| -rw-r--r-- | lab7bonus_fig2.s | 28 | ||||
| -rw-r--r-- | lab7bonus_fig4.s | 29 | ||||
| -rw-r--r-- | lab7bonus_stage2_tb.sv | 35 | ||||
| -rw-r--r-- | lab7bonus_top.sv | 90 | ||||
| -rw-r--r-- | mem/data.txt | 256 | ||||
| -rw-r--r-- | mem/data_cpu_tb.txt | 256 | ||||
| -rw-r--r-- | mem/data_lab8_check.txt | 256 | ||||
| -rw-r--r-- | mem/data_lab8_stage2.txt | 256 | ||||
| -rw-r--r-- | regfile.sv | 45 | ||||
| -rw-r--r-- | shifter.sv | 18 | ||||
| -rw-r--r-- | src/alu.sv | 17 | ||||
| -rw-r--r-- | src/cpu.sv | 94 | ||||
| -rw-r--r-- | src/datapath.sv | 38 | ||||
| -rw-r--r-- | src/lab7bonus_top.sv | 79 | ||||
| -rw-r--r-- | src/regfile.sv | 54 | ||||
| -rw-r--r-- | src/shifter.sv | 12 | ||||
| -rw-r--r-- | src/statemachine.sv | 246 | ||||
| -rw-r--r-- | testbenches/cpu_tb.sv | 41 | ||||
| -rw-r--r-- | testbenches/lab7_autograder_check.sv | 66 | ||||
| -rw-r--r-- | testbenches/lab7bonus_autograder_check.sv | 76 | ||||
| -rw-r--r-- | testbenches/lab7bonus_stage2_tb.sv | 49 | ||||
| -rw-r--r-- | testbenches/wave.do | 66 | ||||
| -rw-r--r-- | trigger.py | 31 |
31 files changed, 1902 insertions, 833 deletions
diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..273c735 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+indent_style = tab
+indent_size = 8
@@ -1,14 +1,34 @@ -[](https://classroom.github.com/a/H84oO7Rx) -[](https://classroom.github.com/online_ide?assignment_repo_id=17389376&assignment_repo_type=AssignmentRepo) -# starter-lab-7-bonus +# RISC-V Machine Source Code for CPU Competition -Lab 7 bonus ONLY: Do NOT use this repository for Lab 7 or your TA will not get -your code during your marking session. +This repository contains the RISC-V machine source code used in the CPEN 211 CPU competition held at the end of the semester. -See the Lab 7 Bonus handout for detailed instructions for what you need to do -for the bonus. +## Performance Overview +- **Main Branch**: Achieves **maximum 5 cycles per instruction**. +- **Competition Results**: Ranked **3rd place** in terms of: + - Efficiency to compute multiple instructions. + - Maximum clock frequency achieved. + - Geometric Mean Speedup (compared to the unoptimized reference version). +- **Pipelined Branch**: An experimental version of the RISC machine with pipelining is available in the `pipelined` branch. Although not fully debugged, it is theoretically **2-3x faster** than the current implementation. + +### Final Ranking and Scores + + +--- + +## Build Instructions +The RISC machine is developed with: +- **Quartus Prime 18.1** +- **ModelSim 10.5b** + +It has been tested on the **Cyclone-V FPGA** using the **DE1-SoC** development board. While other Verilog tools and FPGAs may work, modifications to the top module and pin assignments may be required. + +### Build Process +1. Add all `.sv` files to your project. +2. Set `lab7bonus_top` as your top module. +3. Create or modify `data.txt` to initialize system RAM. + +--- + +## Important Note +This work is the property of **Krish Thakur** and **Warrick Lo**. It **MUST NOT** be copied or reused in any form. Furthermore, this code will no longer function on any version of the CPEN 211 autograder. -IMPORTANT: Ensure your submission includes a Quartus project file and a -Modelsim Project File and that both specify all (System)Verilog files required -to synthesize your CPU or the autograder will not be able to compile your -design and you will get zero marks for the bonus. @@ -1,21 +0,0 @@ - module ALU(Ain,Bin,ALUop,out,Z);
- input [15:0] Ain, Bin;
- input [1:0] ALUop;
- output reg [15:0] out;
- output reg [2:0] Z; //Z[0] = zero flag, Z[1] = neg flag, Z[2] = overflow flag
-
- always_comb begin
- case(ALUop)
- 2'b00 : out = Ain + Bin; //add Ain and Bin
- 2'b01 : out = Ain - Bin; //subtract Ain and Bin
- 2'b10 : out = Ain & Bin; //AND Ain and Bin
- 2'b11 : out = ~Bin; //Negate Bin
- endcase
-
- //make it better by putting it into the add and subtraction above
- Z[0] = out[15]; //negative
- Z[1] = (ALUop == 2'b00) ? ((Ain[15] == Bin[15]) && (out[15] != Ain[15])) :
- (ALUop == 2'b01) ? ((Ain[15] != Bin[15]) && (out[15] != Ain[15])) : 1'b0; //improvements could be made
- Z[2] = out == {16{1'b0}}; //zero
- end
- endmodule
\ No newline at end of file @@ -1,150 +0,0 @@ -`define RST 5'b00000
-`define GetA 5'b00001
-`define GetB 5'b00010
-`define operation 5'b00011
-`define WriteReg 5'b00100
-`define GetACMP 5'b00101
-`define GetBCMP 5'b00110
-`define GetBonly 5'b00111
-`define IF1 5'b01000
-`define IF2 5'b01001
-`define UpdatePC 5'b01010
-`define GetAddr 5'b01011
-`define LoadAddr 5'b01100
-`define StoreAddr 5'b01101
-`define Dout 5'b01110
-`define Dout2 5'b01111
-`define Dout3 5'b10000
-`define Dout4 5'b10001
-
-`define MNONE 2'b00
-`define MREAD 2'b01
-`define MWRITE 2'b10
-
-module cpu(clk,reset,read_data,write_data,mem_addr,mem_cmd,N,V,Z);
- input clk, reset;
- input [15:0] read_data;
- output reg [15:0] write_data;
- output reg [8:0] mem_addr;
- output reg [1:0] mem_cmd;
- output reg N, V, Z;
-
- reg [15:0] inst_reg = 16'bx;
- reg [15:0] next_inst_reg, datapath_out;
- reg [2:0] opcode, readnum, writenum, Z_out;
- reg [1:0] op, nsel, shift, ALUop, vsel;
- reg loada, loadb, loadc, loads, write, asel, bsel,
- load_ir, load_pc, reset_pc, addr_sel, load_addr;
- reg [15:0] sximm8;
- reg [15:0] sximm5;
- reg [4:0] present_state;
-
- reg [15:0] mdata;
- reg [8:0] PC, next_pc = 9'b0;
- reg [8:0] data_addr, next_data_addr;
-
- //three more internal wires
- //later change some of these to wires to make less expensive
-
- datapath DP(clk, readnum, vsel, loada, loadb, shift, asel, bsel, ALUop,
- loadc, loads, writenum, write, Z_out, datapath_out, sximm5, sximm8, mdata);
-
- //if nsel == 00 -> rm nsel == 01 -> rd, nsel == 10 -> rn
- always_comb begin
-
- {opcode, op} = inst_reg[15:11]; //decodin like crazy here
- if (opcode == 3'b100) shift = 2'b00;
- else shift = inst_reg[4:3];
- sximm5 = {{11{inst_reg[4]}}, inst_reg[4:0]};
- sximm8 = {{8{inst_reg[7]}} , inst_reg[7:0]}; //fix this back
- ALUop = op;
-
- case (nsel)
- 2'b00: {readnum, writenum} = {2{inst_reg[2:0]}}; //Rm
- 2'b01: {readnum, writenum} = {2{inst_reg[7:5]}}; //Rd
- 2'b10: {readnum, writenum} = {2{inst_reg[10:8]}}; //Rn
- default: {readnum, writenum} = {writenum, readnum};
- endcase
-
- {Z, V, N} = Z_out; //give out all values
- write_data = datapath_out;
-
- mdata = read_data;
- next_inst_reg = load_ir ? read_data : inst_reg; //load for instructions
-
- next_pc = reset_pc ? 9'b0 : (PC + 1'b1);
- mem_addr = addr_sel ? PC : data_addr;
- next_data_addr = load_addr ? datapath_out[8:0] : data_addr;
- end
-
- // next: first, second and third bit: nsel, second bit loada, third bit loadB, fouth bit asel,
- // fifth bit bsel, sixth and 7th bit shift, 8th and 9th bit aluop, 10th bit loadc, 11bit vsel,
- // 12bit write
- always_ff @(posedge clk) begin
- inst_reg = next_inst_reg;
- data_addr = next_data_addr;
- if (load_pc) PC = next_pc;
-
- casex ({present_state, reset})
- //all roads lead to rome (`wait)
- {4'bxxxx, 1'b1} : {present_state, write, load_pc, reset_pc, load_ir} = {`RST, 4'b0110};
- {`RST, 1'b0} : {present_state, write, addr_sel, load_pc, reset_pc, mem_cmd} = {`IF1, 4'b0100, `MREAD};
- {`IF1, 1'b0} : {present_state, load_ir} = {`IF2, 1'b1};
- {`IF2, 1'b0} : {present_state, addr_sel, load_pc, load_ir, mem_cmd} = {`UpdatePC, 3'b010, `MNONE};
- //make IF1 states+, last state before below is UpdatePC
-
- {`UpdatePC, 1'b0} : begin
- casex ({opcode, op}) //op since ALUop == op
- //move instructions
- 5'b11010: {present_state, nsel, vsel, write, load_pc} = {`WriteReg, 6'b101010}; // 2 clk cycles
- 5'b11000: {present_state, nsel, loada, loadb, load_pc} = {`GetBonly, 5'b00010}; // 3 clk cycles
- //alu instructions
- 5'b101x0: {present_state, nsel, loada, load_pc} = {`GetA, 4'b1010}; //ADD & AND ---> 4 clk cycles //loads A
- 5'b10101: {present_state, nsel, loada, load_pc} = {`GetACMP, 4'b1010}; //CMP ---> 3 clk cycles //loads A
- 5'b10111: {present_state, nsel, loada, loadb, load_pc} = {`GetBonly, 5'b00010}; //MVN ---> 3 clk cycles //loads to B
- //memory instructions
- 5'b01100: {present_state, nsel, loada, loadb, asel, bsel, load_pc, mem_cmd} = {`GetAddr, 7'b1010010, `MREAD}; //LDR
- 5'b10000: {present_state, nsel, loada, loadb, asel, bsel, load_pc} = {`GetAddr, 7'b1010010}; //STR
- //HALT instruction
- 5'b111xx: {present_state, load_pc} = {`UpdatePC, 1'b0}; //will be stuck here until reset
- endcase
- end
-
- //ADD & AND branch
- {`GetA, 1'b0} : {present_state, nsel, loadb, loada} = {`GetB, 4'b0010}; //loads B
- {`GetB, 1'b0} : {present_state, asel, bsel, loadc, loads} = {`operation, 4'b0010}; //performs operations
-
- //for writing only from B to Rd
- {`GetBonly, 1'b0} : {present_state, asel, bsel, loadc, loads} = {`operation, 4'b1010};
-
- //Get the (shifted) memory address (LDR)
- {`GetAddr, 1'b0} : begin
- case (opcode)
- 3'b011: {present_state, loada, loadb, loadc, load_addr, addr_sel, mem_cmd} = {`Dout, 5'b00110, `MREAD}; //might need an extra state for dout
- 3'b100: {present_state, loada, loadb, loadc, load_addr, addr_sel} = {`StoreAddr, 5'b00110};
- endcase
- end
- {`Dout, 1'b0} : begin //wait for RAM
- case (opcode)
- 3'b011: present_state = `Dout2;
- 3'b100: {present_state, loada, loadb, loadc, load_addr, mem_cmd} = {`Dout4, 4'b0010, `MWRITE};
- endcase
- end
- {`Dout2, 1'b0} : {present_state, load_addr} = {`LoadAddr, 1'b0};
- {`LoadAddr, 1'b0} : {present_state, nsel, vsel, write, loadc, load_addr, mem_cmd} = {`Dout3, 7'b0111100, `MREAD};
- {`Dout3, 1'b0} : {present_state, mem_cmd, write} = {`WriteReg, `MNONE, 1'b0};
-
- {`StoreAddr, 1'b0} : {present_state, nsel, loada, loadb, asel, bsel, load_addr} = {`Dout, 7'b0101101};
- {`Dout4, 1'b0} : {present_state, write} = {`WriteReg, 1'b0};
-
- //CMP branch
- {`GetACMP, 1'b0} : {present_state, nsel, loadb, loada} = {`GetBCMP, 4'b0010}; //loads B
- {`GetBCMP, 1'b0} : {present_state, asel, bsel, loadc, loads} = {`WriteReg, 4'b0001}; //performs operations and writes into status
-
- //write to Rd
- {`operation, 1'b0} : {present_state, nsel, vsel, write} = {`WriteReg, 5'b01001}; //writing into the register
- //waiter/reset
- {`WriteReg, 1'b0} : {present_state, loada, loadb, loadc, loads, mem_cmd} = {`RST, 4'b0000, `MNONE}; //extra cycle for values to got through (should I go reset or IF1)
- endcase
- end
- endmodule
\ No newline at end of file diff --git a/data.txt b/data.txt deleted file mode 100644 index 1f1ecbd..0000000 --- a/data.txt +++ /dev/null @@ -1,256 +0,0 @@ -@00 1101000000000101 -@01 0110000000100000 -@02 1101001000000110 -@03 1000001000100000 -@04 1110000000000000 -@05 1010101111001101 -@06 0000000000000000 -@07 0000000000000000 -@08 0000000000000000 -@09 0000000000000000 -@0A 0000000000000000 -@0B 0000000000000000 -@0C 0000000000000000 -@0D 0000000000000000 -@0E 0000000000000000 -@0F 0000000000000000 -@10 0000000000000000 -@11 0000000000000000 -@12 0000000000000000 -@13 0000000000000000 -@14 0000000000000000 -@15 0000000000000000 -@16 0000000000000000 -@17 0000000000000000 -@18 0000000000000000 -@19 0000000000000000 -@1A 0000000000000000 -@1B 0000000000000000 -@1C 0000000000000000 -@1D 0000000000000000 -@1E 0000000000000000 -@1F 0000000000000000 -@20 0000000000000000 -@21 0000000000000000 -@22 0000000000000000 -@23 0000000000000000 -@24 0000000000000000 -@25 0000000000000000 -@26 0000000000000000 -@27 0000000000000000 -@28 0000000000000000 -@29 0000000000000000 -@2A 0000000000000000 -@2B 0000000000000000 -@2C 0000000000000000 -@2D 0000000000000000 -@2E 0000000000000000 -@2F 0000000000000000 -@30 0000000000000000 -@31 0000000000000000 -@32 0000000000000000 -@33 0000000000000000 -@34 0000000000000000 -@35 0000000000000000 -@36 0000000000000000 -@37 0000000000000000 -@38 0000000000000000 -@39 0000000000000000 -@3A 0000000000000000 -@3B 0000000000000000 -@3C 0000000000000000 -@3D 0000000000000000 -@3E 0000000000000000 -@3F 0000000000000000 -@40 0000000000000000 -@41 0000000000000000 -@42 0000000000000000 -@43 0000000000000000 -@44 0000000000000000 -@45 0000000000000000 -@46 0000000000000000 -@47 0000000000000000 -@48 0000000000000000 -@49 0000000000000000 -@4A 0000000000000000 -@4B 0000000000000000 -@4C 0000000000000000 -@4D 0000000000000000 -@4E 0000000000000000 -@4F 0000000000000000 -@50 0000000000000000 -@51 0000000000000000 -@52 0000000000000000 -@53 0000000000000000 -@54 0000000000000000 -@55 0000000000000000 -@56 0000000000000000 -@57 0000000000000000 -@58 0000000000000000 -@59 0000000000000000 -@5A 0000000000000000 -@5B 0000000000000000 -@5C 0000000000000000 -@5D 0000000000000000 -@5E 0000000000000000 -@5F 0000000000000000 -@60 0000000000000000 -@61 0000000000000000 -@62 0000000000000000 -@63 0000000000000000 -@64 0000000000000000 -@65 0000000000000000 -@66 0000000000000000 -@67 0000000000000000 -@68 0000000000000000 -@69 0000000000000000 -@6A 0000000000000000 -@6B 0000000000000000 -@6C 0000000000000000 -@6D 0000000000000000 -@6E 0000000000000000 -@6F 0000000000000000 -@70 0000000000000000 -@71 0000000000000000 -@72 0000000000000000 -@73 0000000000000000 -@74 0000000000000000 -@75 0000000000000000 -@76 0000000000000000 -@77 0000000000000000 -@78 0000000000000000 -@79 0000000000000000 -@7A 0000000000000000 -@7B 0000000000000000 -@7C 0000000000000000 -@7D 0000000000000000 -@7E 0000000000000000 -@7F 0000000000000000 -@80 0000000000000000 -@81 0000000000000000 -@82 0000000000000000 -@83 0000000000000000 -@84 0000000000000000 -@85 0000000000000000 -@86 0000000000000000 -@87 0000000000000000 -@88 0000000000000000 -@89 0000000000000000 -@8A 0000000000000000 -@8B 0000000000000000 -@8C 0000000000000000 -@8D 0000000000000000 -@8E 0000000000000000 -@8F 0000000000000000 -@90 0000000000000000 -@91 0000000000000000 -@92 0000000000000000 -@93 0000000000000000 -@94 0000000000000000 -@95 0000000000000000 -@96 0000000000000000 -@97 0000000000000000 -@98 0000000000000000 -@99 0000000000000000 -@9A 0000000000000000 -@9B 0000000000000000 -@9C 0000000000000000 -@9D 0000000000000000 -@9E 0000000000000000 -@9F 0000000000000000 -@A0 0000000000000000 -@A1 0000000000000000 -@A2 0000000000000000 -@A3 0000000000000000 -@A4 0000000000000000 -@A5 0000000000000000 -@A6 0000000000000000 -@A7 0000000000000000 -@A8 0000000000000000 -@A9 0000000000000000 -@AA 0000000000000000 -@AB 0000000000000000 -@AC 0000000000000000 -@AD 0000000000000000 -@AE 0000000000000000 -@AF 0000000000000000 -@B0 0000000000000000 -@B1 0000000000000000 -@B2 0000000000000000 -@B3 0000000000000000 -@B4 0000000000000000 -@B5 0000000000000000 -@B6 0000000000000000 -@B7 0000000000000000 -@B8 0000000000000000 -@B9 0000000000000000 -@BA 0000000000000000 -@BB 0000000000000000 -@BC 0000000000000000 -@BD 0000000000000000 -@BE 0000000000000000 -@BF 0000000000000000 -@C0 0000000000000000 -@C1 0000000000000000 -@C2 0000000000000000 -@C3 0000000000000000 -@C4 0000000000000000 -@C5 0000000000000000 -@C6 0000000000000000 -@C7 0000000000000000 -@C8 0000000000000000 -@C9 0000000000000000 -@CA 0000000000000000 -@CB 0000000000000000 -@CC 0000000000000000 -@CD 0000000000000000 -@CE 0000000000000000 -@CF 0000000000000000 -@D0 0000000000000000 -@D1 0000000000000000 -@D2 0000000000000000 -@D3 0000000000000000 -@D4 0000000000000000 -@D5 0000000000000000 -@D6 0000000000000000 -@D7 0000000000000000 -@D8 0000000000000000 -@D9 0000000000000000 -@DA 0000000000000000 -@DB 0000000000000000 -@DC 0000000000000000 -@DD 0000000000000000 -@DE 0000000000000000 -@DF 0000000000000000 -@E0 0000000000000000 -@E1 0000000000000000 -@E2 0000000000000000 -@E3 0000000000000000 -@E4 0000000000000000 -@E5 0000000000000000 -@E6 0000000000000000 -@E7 0000000000000000 -@E8 0000000000000000 -@E9 0000000000000000 -@EA 0000000000000000 -@EB 0000000000000000 -@EC 0000000000000000 -@ED 0000000000000000 -@EE 0000000000000000 -@EF 0000000000000000 -@F0 0000000000000000 -@F1 0000000000000000 -@F2 0000000000000000 -@F3 0000000000000000 -@F4 0000000000000000 -@F5 0000000000000000 -@F6 0000000000000000 -@F7 0000000000000000 -@F8 0000000000000000 -@F9 0000000000000000 -@FA 0000000000000000 -@FB 0000000000000000 -@FC 0000000000000000 -@FD 0000000000000000 -@FE 0000000000000000 -@FF 0000000000000000
\ No newline at end of file diff --git a/datapath.sv b/datapath.sv deleted file mode 100644 index ed74541..0000000 --- a/datapath.sv +++ /dev/null @@ -1,48 +0,0 @@ -module datapath(clk, readnum, vsel, loada, loadb, shift, asel, bsel, ALUop,
- loadc, loads, writenum, write, Z_out, datapath_out, sximm5, sximm8, mdata);
-
- input clk;
- input write, loada, loadb, asel, bsel, loadc, loads;
- input [2:0] readnum, writenum;
- input [1:0] shift, ALUop, vsel;
- input [15:0] sximm8;
- input [15:0] sximm5;
- input [15:0] mdata;
-
- output reg [15:0] datapath_out;
- output reg [2:0] Z_out;
-
- reg [15:0] data_in, in, Aout;
- reg [7:0] PC = 8'b0; // fix later
- reg [15:0] Ain, Bin = {16{1'b0}};
- wire [15:0] data_out, sout, out;
- wire [2:0] Z;
- //initialize all ins and outs and internal wires above
-
- regfile REGFILE(data_in,writenum,write,readnum,clk,data_out);
- shifter SHIFTER(in,shift,sout);
- ALU alu(Ain,Bin,ALUop,out,Z);
-
- //the three components
-
- always_comb begin
- case (vsel)
- 2'b00: data_in = datapath_out; //also known as C
- 2'b01: data_in = {8'b0, PC};
- 2'b10: data_in = sximm8; //immediate sign extended
- 2'b11: data_in = mdata;
- endcase
-
- Bin = bsel ? sximm5 : sout; //the Bin multiplexer
- Ain = asel ? ({16{1'b0}}) : Aout; //the Ain multiplexer
- end
-
- always_ff @(posedge clk) begin
- //push all when clk is pressed
- if (loadb) in = data_out;
- if (loada) Aout = data_out;
- if (loadc) datapath_out = out;
- if (loads) Z_out = Z;
- end
-
-endmodule
\ No newline at end of file diff --git a/images/rankings.png b/images/rankings.png Binary files differnew file mode 100644 index 0000000..5c59454 --- /dev/null +++ b/images/rankings.png diff --git a/lab7bonus_autograder_check.sv b/lab7bonus_autograder_check.sv deleted file mode 100644 index eac9f67..0000000 --- a/lab7bonus_autograder_check.sv +++ /dev/null @@ -1,71 +0,0 @@ -module lab7bonus_check_tb; - reg [3:0] KEY; - reg [9:0] SW; - wire [9:0] LEDR; - wire [6:0] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5; - reg err; - reg CLOCK_50; - - lab7bonus_top DUT(KEY,SW,LEDR,HEX0,HEX1,HEX2,HEX3,HEX4,HEX5,CLOCK_50); - - initial forever begin - CLOCK_50 = 0; #5; - CLOCK_50 = 1; #5; - end - - initial begin - err = 0; - KEY[1] = 1'b0; // reset asserted - // check if program from Figure 2 in Lab 8 handout can be found loaded in memory - if (DUT.MEM.mem[0] !== 16'b1101000000001111) begin err = 1; $display("FAILED: mem[0] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end - if (DUT.MEM.mem[1] !== 16'b0110000000000000) begin err = 1; $display("FAILED: mem[1] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end - if (DUT.MEM.mem[2] !== 16'b1101000100000000) begin err = 1; $display("FAILED: mem[2] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end - if (DUT.MEM.mem[3] !== 16'b1101001000000000) begin err = 1; $display("FAILED: mem[3] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end - if (DUT.MEM.mem[4] !== 16'b1101001100010000) begin err = 1; $display("FAILED: mem[4] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end - if (DUT.MEM.mem[5] !== 16'b1101010000000001) begin err = 1; $display("FAILED: mem[5] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end - if (DUT.MEM.mem[6] !== 16'b1010001110100001) begin err = 1; $display("FAILED: mem[6] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end - if (DUT.MEM.mem[7] !== 16'b0110010110100000) begin err = 1; $display("FAILED: mem[7] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end - if (DUT.MEM.mem[8] !== 16'b1010001001000101) begin err = 1; $display("FAILED: mem[8] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end - if (DUT.MEM.mem[9] !== 16'b1010000100100100) begin err = 1; $display("FAILED: mem[9] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end - if (DUT.MEM.mem[10] !== 16'b1010100100000000) begin err = 1; $display("FAILED: mem[10] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end - if (DUT.MEM.mem[11] !== 16'b0010001111111010) begin err = 1; $display("FAILED: mem[11] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end - if (DUT.MEM.mem[12] !== 16'b1101001100010100) begin err = 1; $display("FAILED: mem[12] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end - if (DUT.MEM.mem[13] !== 16'b1000001101000000) begin err = 1; $display("FAILED: mem[13] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end - if (DUT.MEM.mem[14] !== 16'b1110000000000000) begin err = 1; $display("FAILED: mem[14] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end - if (DUT.MEM.mem[15] !== 16'b0000000000000100) begin err = 1; $display("FAILED: mem[15] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end - if (DUT.MEM.mem[16] !== 16'b0000000000110010) begin err = 1; $display("FAILED: mem[16] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end - if (DUT.MEM.mem[17] !== 16'b0000000011001000) begin err = 1; $display("FAILED: mem[17] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end - if (DUT.MEM.mem[18] !== 16'b0000000001100100) begin err = 1; $display("FAILED: mem[18] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end - if (DUT.MEM.mem[19] !== 16'b0000000111110100) begin err = 1; $display("FAILED: mem[19] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end - if (DUT.MEM.mem[20] !== 16'b1011101011011101) begin err = 1; $display("FAILED: mem[20] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end - if (DUT.MEM.mem[21] !== 16'b0000000000000000) begin err = 1; $display("FAILED: mem[21] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end - - #10; // wait until next falling edge of clock - KEY[1] = 1'b1; // reset de-asserted, PC still undefined if as in Figure 4 - - #10; // waiting for RST state to cause reset of PC - if (DUT.CPU.PC !== 9'h0) begin err = 1; $display("FAILED: PC did not reset to 0."); $stop; end - - // If your simlation never gets past the the line below, check if your CMP instruction is working - @(posedge LEDR[8]); // set LEDR[8] to one when executing HALT - - // NOTE: your program counter register output should be called PC and be inside a module with instance name CPU - // NOTE: if HALT is working, PC won't change after reaching 0xE - if (DUT.CPU.PC !== 9'hF) begin err = 1; $display("FAILED: PC at HALT is incorrect."); $stop; end - if (DUT.CPU.DP.REGFILE.R4 !== 16'h1) begin err = 1; $display("FAILED: R4 incorrect at exit; did MOV R4,#1 not work?"); $stop; end - if (DUT.CPU.DP.REGFILE.R0 !== 16'h4) begin err = 1; $display("FAILED: R0 incorrect at exit; did LDR R0,[R0] not work?"); $stop; end - - // check memory contents for result - if (DUT.MEM.mem[8'h14] === 16'h0) begin - err = 1; - $display("FAILED: mem[0x14] (result) is wrong;"); - if (DUT.CPU.DP.REGFILE.R3 === 16'h10) - $display(" hint: check if your BLT instruction skipped MOV R3, result"); - $stop; - end - if (DUT.MEM.mem[8'h14] !== 16'd850) begin err = 1; $display("FAILED: mem[0x14] (result) is wrong;"); $stop; end - - if (~err) $display("INTERFACE OK"); - $stop; - end -endmodule diff --git a/lab7bonus_fig2.s b/lab7bonus_fig2.s deleted file mode 100644 index 35fcc69..0000000 --- a/lab7bonus_fig2.s +++ /dev/null @@ -1,28 +0,0 @@ - MOV R0,N // R0 = address of variable N - LDR R0,[R0] // R0 = 4 - MOV R1,#0 // R1 = 0; R1 is "i" - MOV R2,#0 // R2 = 0; R2 is "sum" - MOV R3,amount // R3 = base address of array "amount" - MOV R4,#1 // R4 = 1 - -LOOP: // for(i=0; i<N; i++) sum = sum + amount[i]; - ADD R5,R3,R1 // R5 = address of amount[i] - LDR R5,[R5] // R5 = amount[i] - ADD R2,R2,R5 // sum = sum + amount[i] - ADD R1,R1,R4 // i++ - CMP R1,R0 - BLT LOOP // if i < N goto LOOP - - MOV R3,result - STR R2,[R3] // result = sum - HALT - -N: - .word 4 -amount: - .word 50 - .word 200 - .word 100 - .word 500 -result: - .word 0xBADD diff --git a/lab7bonus_fig4.s b/lab7bonus_fig4.s deleted file mode 100644 index 35e20e0..0000000 --- a/lab7bonus_fig4.s +++ /dev/null @@ -1,29 +0,0 @@ - MOV R6,stack_begin - LDR R6,[R6] // initialize stack pointer - MOV R4, result // R4 contains address of result - MOV R3,#0 - STR R3,[R4] // result = 0; - MOV R0,#1 // R0 contains first parameter - MOV R1,#5 // R1 contains second parameter - MOV R2,#9 // R2 contains third parameter - MOV R3,#20 // R3 contains fourth parameter - BL leaf_example // call leaf_example(1,5,9,20); - STR R0,[R4] // result = leaf_example(1,5,9,20); - HALT -leaf_example: - STR R4,[R6] // save R4 for use afterwards - STR R5,[R6,#-1] // save R5 for use afterwards - ADD R4,R0,R1 // R4 = g + h - ADD R5,R2,R3 // R5 = i + j - MVN R5,R5 // R5 = ~(i + j) - ADD R4,R4,R5 // R4 = (g + h) + ~(i + j) - MOV R5,#1 - ADD R4,R4,R5 // R4 = (g + h) - (i + j) - MOV R0,R4 // R0 = return value (g + h) - (i + j) - LDR R5,[R6,#-1] // restore saved contents of R5 - LDR R4,[R6] // restore saved contents of R4 - BX R7 // return control to caller -stack_begin: - .word 0xFF -result: - .word 0xCCCC diff --git a/lab7bonus_stage2_tb.sv b/lab7bonus_stage2_tb.sv deleted file mode 100644 index aced299..0000000 --- a/lab7bonus_stage2_tb.sv +++ /dev/null @@ -1,35 +0,0 @@ -module lab7bonus_stage2_tb; - reg [3:0] KEY; - reg [9:0] SW; - wire [9:0] LEDR; - wire [6:0] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5; - reg err; - reg CLOCK_50; - - lab7bonus_top DUT(KEY,SW,LEDR,HEX0,HEX1,HEX2,HEX3,HEX4,HEX5,CLOCK_50); - - initial forever begin - CLOCK_50 = 0; #5; - CLOCK_50 = 1; #5; - end - wire break = (LEDR[8] == 1'b1); - initial begin - err = 0; - KEY[1] = 1'b0; // reset asserted - #10; // wait until next falling edge of clock - KEY[1] = 1'b1; // reset de-asserted, PC still undefined if as in Figure 4 - while (~break) begin - // Change the following line to wait until your CPU starts to you fetch - // the next instruction (e.g., IF1 state from Lab 7 or equivalent in - // your design). DUT.CPU.FSM is not required for by the autograder - // for Lab 8. - @(posedge (DUT.CPU.FSM.present_state == `YOUR_IF1_STATE) or posedge break); - - @(negedge CLOCK_50); // show advance to negative edge of clock - $display("PC = %h", DUT.CPU.PC); - end - if (DUT.MEM.mem[25] !== -16'd23) begin err = 1; $display("FAILED: mem[25] wrong"); $stop; end - if (~err) $display("PASSED"); - $stop; - end -endmodule diff --git a/lab7bonus_top.sv b/lab7bonus_top.sv deleted file mode 100644 index d76cf7c..0000000 --- a/lab7bonus_top.sv +++ /dev/null @@ -1,90 +0,0 @@ -`define MNONE 2'b00
-`define MREAD 2'b01
-`define MWRITE 2'b10
-
-module lab7bonus_top(KEY,SW,LEDR,HEX0,HEX1,HEX2,HEX3,HEX4,HEX5);
- input [3:0] KEY;
- input [9:0] SW;
- output reg [9:0] LEDR;
- output [6:0] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5;
-
- reg [8:0] mem_addr;
- reg [7:0] read_address, write_address, next_LEDR, onto_LEDR;
- reg write, enable;
- reg [15:0] dout, din, read_data, write_data, ir;
- wire [1:0] mem_cmd;
- reg msel;
- wire N, V, Z;
-
-
- RAM MEM(.clk (~KEY[0]),
- .read_address (read_address),
- .write_address (write_address),
- .write (write),
- .din (din),
- .dout (dout)
- );
-
- cpu CPU(.clk (~KEY[0]),
- .reset (~KEY[1]),
- .read_data (read_data),
- .write_data(write_data),
- .mem_addr(mem_addr),
- .mem_cmd(mem_cmd),
- .N(N),
- .V(V),
- .Z(Z)
- );
-
-
- always_comb begin
-
- msel = mem_addr[8]; //checks the last bit to check the indicated address. 0 would mean below 255 and 1 would mean abouve 256
- write = ({mem_cmd, msel} == {`MWRITE, 1'b0}); //write choosing
- enable = ({mem_cmd, msel} == {`MREAD, 1'b0}); //the and gates and stuff
-
- write_address = mem_addr[7:0];
- read_address = mem_addr[7:0];
- din = write_data;
-
- read_data = enable ? dout : {16{1'bz}}; //tri-state driver
-
- if ({mem_addr, mem_cmd} == {9'h140, `MREAD}) read_data = {8'b0, SW[7:0]}; //desing own logic this reads the switches if mem_cmd and addr are according
- else read_data = read_data;
-
- if ({mem_addr, mem_cmd} == {9'h100, `MWRITE}) next_LEDR = write_data[7:0]; //design own logic this writes to the switches if mem_cmd and addr are according
- else next_LEDR = 8'bx;;
-
- end
-
- always_ff @(posedge ~KEY[0]) begin
- LEDR[7:0] = next_LEDR;
- end
-
-endmodule
-
-
-// Ram block obtained form slide set 11
-module RAM(clk,read_address,write_address,write,din,dout);
- parameter data_width = 16;
- parameter addr_width = 8;
- parameter filename = "data.txt";
-
- input clk;
- input [addr_width-1:0] read_address, write_address;
- input write;
- input [data_width-1:0] din;
- output [data_width-1:0] dout;
- reg [data_width-1:0] dout;
-
- reg [data_width-1:0] mem [2**addr_width-1:0];
-
- initial $readmemb(filename, mem);
-
- always @ (posedge clk) begin
- if (write)
- mem[write_address] <= din;
- dout <= mem[read_address]; // dout doesn't get din in this clock cycle
- // (this is due to Verilog non-blocking assignment "<=")
- end
-endmodule
diff --git a/mem/data.txt b/mem/data.txt new file mode 100644 index 0000000..533cef4 --- /dev/null +++ b/mem/data.txt @@ -0,0 +1,256 @@ +@00 1101000000000101 +@01 0110000000100000 +@02 1101001000000110 +@03 1000001000100000 +@04 1110000000000000 +@05 1010101111001101 +@06 0000000000000000 +@07 0000000000000000 +@08 0000000000000000 +@09 0000000000000000 +@0a 0000000000000000 +@0b 0000000000000000 +@0c 0000000000000000 +@0d 0000000000000000 +@0e 0000000000000000 +@0f 0000000000000000 +@10 0000000000000000 +@11 0000000000000000 +@12 0000000000000000 +@13 0000000000000000 +@14 0000000000000000 +@15 0000000000000000 +@16 0000000000000000 +@17 0000000000000000 +@18 0000000000000000 +@19 0000000000000000 +@1a 0000000000000000 +@1b 0000000000000000 +@1c 0000000000000000 +@1d 0000000000000000 +@1e 0000000000000000 +@1f 0000000000000000 +@20 0000000000000000 +@21 0000000000000000 +@22 0000000000000000 +@23 0000000000000000 +@24 0000000000000000 +@25 0000000000000000 +@26 0000000000000000 +@27 0000000000000000 +@28 0000000000000000 +@29 0000000000000000 +@2a 0000000000000000 +@2b 0000000000000000 +@2c 0000000000000000 +@2d 0000000000000000 +@2e 0000000000000000 +@2f 0000000000000000 +@30 0000000000000000 +@31 0000000000000000 +@32 0000000000000000 +@33 0000000000000000 +@34 0000000000000000 +@35 0000000000000000 +@36 0000000000000000 +@37 0000000000000000 +@38 0000000000000000 +@39 0000000000000000 +@3a 0000000000000000 +@3b 0000000000000000 +@3c 0000000000000000 +@3d 0000000000000000 +@3e 0000000000000000 +@3f 0000000000000000 +@40 0000000000000000 +@41 0000000000000000 +@42 0000000000000000 +@43 0000000000000000 +@44 0000000000000000 +@45 0000000000000000 +@46 0000000000000000 +@47 0000000000000000 +@48 0000000000000000 +@49 0000000000000000 +@4a 0000000000000000 +@4b 0000000000000000 +@4c 0000000000000000 +@4d 0000000000000000 +@4e 0000000000000000 +@4f 0000000000000000 +@50 0000000000000000 +@51 0000000000000000 +@52 0000000000000000 +@53 0000000000000000 +@54 0000000000000000 +@55 0000000000000000 +@56 0000000000000000 +@57 0000000000000000 +@58 0000000000000000 +@59 0000000000000000 +@5a 0000000000000000 +@5b 0000000000000000 +@5c 0000000000000000 +@5d 0000000000000000 +@5e 0000000000000000 +@5f 0000000000000000 +@60 0000000000000000 +@61 0000000000000000 +@62 0000000000000000 +@63 0000000000000000 +@64 0000000000000000 +@65 0000000000000000 +@66 0000000000000000 +@67 0000000000000000 +@68 0000000000000000 +@69 0000000000000000 +@6a 0000000000000000 +@6b 0000000000000000 +@6c 0000000000000000 +@6d 0000000000000000 +@6e 0000000000000000 +@6f 0000000000000000 +@70 0000000000000000 +@71 0000000000000000 +@72 0000000000000000 +@73 0000000000000000 +@74 0000000000000000 +@75 0000000000000000 +@76 0000000000000000 +@77 0000000000000000 +@78 0000000000000000 +@79 0000000000000000 +@7a 0000000000000000 +@7b 0000000000000000 +@7c 0000000000000000 +@7d 0000000000000000 +@7e 0000000000000000 +@7f 0000000000000000 +@80 0000000000000000 +@81 0000000000000000 +@82 0000000000000000 +@83 0000000000000000 +@84 0000000000000000 +@85 0000000000000000 +@86 0000000000000000 +@87 0000000000000000 +@88 0000000000000000 +@89 0000000000000000 +@8a 0000000000000000 +@8b 0000000000000000 +@8c 0000000000000000 +@8d 0000000000000000 +@8e 0000000000000000 +@8f 0000000000000000 +@90 0000000000000000 +@91 0000000000000000 +@92 0000000000000000 +@93 0000000000000000 +@94 0000000000000000 +@95 0000000000000000 +@96 0000000000000000 +@97 0000000000000000 +@98 0000000000000000 +@99 0000000000000000 +@9a 0000000000000000 +@9b 0000000000000000 +@9c 0000000000000000 +@9d 0000000000000000 +@9e 0000000000000000 +@9f 0000000000000000 +@a0 0000000000000000 +@a1 0000000000000000 +@a2 0000000000000000 +@a3 0000000000000000 +@a4 0000000000000000 +@a5 0000000000000000 +@a6 0000000000000000 +@a7 0000000000000000 +@a8 0000000000000000 +@a9 0000000000000000 +@aa 0000000000000000 +@ab 0000000000000000 +@ac 0000000000000000 +@ad 0000000000000000 +@ae 0000000000000000 +@af 0000000000000000 +@b0 0000000000000000 +@b1 0000000000000000 +@b2 0000000000000000 +@b3 0000000000000000 +@b4 0000000000000000 +@b5 0000000000000000 +@b6 0000000000000000 +@b7 0000000000000000 +@b8 0000000000000000 +@b9 0000000000000000 +@ba 0000000000000000 +@bb 0000000000000000 +@bc 0000000000000000 +@bd 0000000000000000 +@be 0000000000000000 +@bf 0000000000000000 +@c0 0000000000000000 +@c1 0000000000000000 +@c2 0000000000000000 +@c3 0000000000000000 +@c4 0000000000000000 +@c5 0000000000000000 +@c6 0000000000000000 +@c7 0000000000000000 +@c8 0000000000000000 +@c9 0000000000000000 +@ca 0000000000000000 +@cb 0000000000000000 +@cc 0000000000000000 +@cd 0000000000000000 +@ce 0000000000000000 +@cf 0000000000000000 +@d0 0000000000000000 +@d1 0000000000000000 +@d2 0000000000000000 +@d3 0000000000000000 +@d4 0000000000000000 +@d5 0000000000000000 +@d6 0000000000000000 +@d7 0000000000000000 +@d8 0000000000000000 +@d9 0000000000000000 +@da 0000000000000000 +@db 0000000000000000 +@dc 0000000000000000 +@dd 0000000000000000 +@de 0000000000000000 +@df 0000000000000000 +@e0 0000000000000000 +@e1 0000000000000000 +@e2 0000000000000000 +@e3 0000000000000000 +@e4 0000000000000000 +@e5 0000000000000000 +@e6 0000000000000000 +@e7 0000000000000000 +@e8 0000000000000000 +@e9 0000000000000000 +@ea 0000000000000000 +@eb 0000000000000000 +@ec 0000000000000000 +@ed 0000000000000000 +@ee 0000000000000000 +@ef 0000000000000000 +@f0 0000000000000000 +@f1 0000000000000000 +@f2 0000000000000000 +@f3 0000000000000000 +@f4 0000000000000000 +@f5 0000000000000000 +@f6 0000000000000000 +@f7 0000000000000000 +@f8 0000000000000000 +@f9 0000000000000000 +@fa 0000000000000000 +@fb 0000000000000000 +@fc 0000000000000000 +@fd 0000000000000000 +@fe 0000000000000000 +@ff 0000000000000000 diff --git a/mem/data_cpu_tb.txt b/mem/data_cpu_tb.txt new file mode 100644 index 0000000..56a4210 --- /dev/null +++ b/mem/data_cpu_tb.txt @@ -0,0 +1,256 @@ +@00 1101000000000001 +@01 1101000111101001 +@02 1101001010101010 +@03 1100000001101000 +@04 1100000010000001 +@05 1100000010110011 +@06 1010000011000011 +@07 1010001111101011 +@08 1010001011100000 +@09 1101001000000000 +@0a 1011100001000010 +@0b 1011100011100111 +@0c 1011100010100001 +@0d 1010101100000011 +@0e 1010101000000001 +@0f 1010101000000011 +@10 1011000000000000 +@11 1011001000100010 +@12 1011000000000111 +@13 1101000000000111 +@14 1101000100000010 +@15 1010100000000001 +@16 1010100100000000 +@17 1010100000001000 +@18 1101010101000000 +@19 1100000010101101 +@1a 1100000010101101 +@1b 1100000010101101 +@1c 1100000010101101 +@1d 1100000010101101 +@1e 1100000010101101 +@1f 1100000010101101 +@20 1100000010101101 +@21 1100000010101101 +@22 1010110100000001 +@23 1101000000000111 +@24 1011100011100000 +@25 1011100011101000 +@26 1111111111111111 +@27 0000000000000000 +@28 0000000000000000 +@29 0000000000000000 +@2a 0000000000000000 +@2b 0000000000000000 +@2c 0000000000000000 +@2d 0000000000000000 +@2e 0000000000000000 +@2f 0000000000000000 +@30 0000000000000000 +@31 0000000000000000 +@32 0000000000000000 +@33 0000000000000000 +@34 0000000000000000 +@35 0000000000000000 +@36 0000000000000000 +@37 0000000000000000 +@38 0000000000000000 +@39 0000000000000000 +@3a 0000000000000000 +@3b 0000000000000000 +@3c 0000000000000000 +@3d 0000000000000000 +@3e 0000000000000000 +@3f 0000000000000000 +@40 0000000000000000 +@41 0000000000000000 +@42 0000000000000000 +@43 0000000000000000 +@44 0000000000000000 +@45 0000000000000000 +@46 0000000000000000 +@47 0000000000000000 +@48 0000000000000000 +@49 0000000000000000 +@4a 0000000000000000 +@4b 0000000000000000 +@4c 0000000000000000 +@4d 0000000000000000 +@4e 0000000000000000 +@4f 0000000000000000 +@50 0000000000000000 +@51 0000000000000000 +@52 0000000000000000 +@53 0000000000000000 +@54 0000000000000000 +@55 0000000000000000 +@56 0000000000000000 +@57 0000000000000000 +@58 0000000000000000 +@59 0000000000000000 +@5a 0000000000000000 +@5b 0000000000000000 +@5c 0000000000000000 +@5d 0000000000000000 +@5e 0000000000000000 +@5f 0000000000000000 +@60 0000000000000000 +@61 0000000000000000 +@62 0000000000000000 +@63 0000000000000000 +@64 0000000000000000 +@65 0000000000000000 +@66 0000000000000000 +@67 0000000000000000 +@68 0000000000000000 +@69 0000000000000000 +@6a 0000000000000000 +@6b 0000000000000000 +@6c 0000000000000000 +@6d 0000000000000000 +@6e 0000000000000000 +@6f 0000000000000000 +@70 0000000000000000 +@71 0000000000000000 +@72 0000000000000000 +@73 0000000000000000 +@74 0000000000000000 +@75 0000000000000000 +@76 0000000000000000 +@77 0000000000000000 +@78 0000000000000000 +@79 0000000000000000 +@7a 0000000000000000 +@7b 0000000000000000 +@7c 0000000000000000 +@7d 0000000000000000 +@7e 0000000000000000 +@7f 0000000000000000 +@80 0000000000000000 +@81 0000000000000000 +@82 0000000000000000 +@83 0000000000000000 +@84 0000000000000000 +@85 0000000000000000 +@86 0000000000000000 +@87 0000000000000000 +@88 0000000000000000 +@89 0000000000000000 +@8a 0000000000000000 +@8b 0000000000000000 +@8c 0000000000000000 +@8d 0000000000000000 +@8e 0000000000000000 +@8f 0000000000000000 +@90 0000000000000000 +@91 0000000000000000 +@92 0000000000000000 +@93 0000000000000000 +@94 0000000000000000 +@95 0000000000000000 +@96 0000000000000000 +@97 0000000000000000 +@98 0000000000000000 +@99 0000000000000000 +@9a 0000000000000000 +@9b 0000000000000000 +@9c 0000000000000000 +@9d 0000000000000000 +@9e 0000000000000000 +@9f 0000000000000000 +@a0 0000000000000000 +@a1 0000000000000000 +@a2 0000000000000000 +@a3 0000000000000000 +@a4 0000000000000000 +@a5 0000000000000000 +@a6 0000000000000000 +@a7 0000000000000000 +@a8 0000000000000000 +@a9 0000000000000000 +@aa 0000000000000000 +@ab 0000000000000000 +@ac 0000000000000000 +@ad 0000000000000000 +@ae 0000000000000000 +@af 0000000000000000 +@b0 0000000000000000 +@b1 0000000000000000 +@b2 0000000000000000 +@b3 0000000000000000 +@b4 0000000000000000 +@b5 0000000000000000 +@b6 0000000000000000 +@b7 0000000000000000 +@b8 0000000000000000 +@b9 0000000000000000 +@ba 0000000000000000 +@bb 0000000000000000 +@bc 0000000000000000 +@bd 0000000000000000 +@be 0000000000000000 +@bf 0000000000000000 +@c0 0000000000000000 +@c1 0000000000000000 +@c2 0000000000000000 +@c3 0000000000000000 +@c4 0000000000000000 +@c5 0000000000000000 +@c6 0000000000000000 +@c7 0000000000000000 +@c8 0000000000000000 +@c9 0000000000000000 +@ca 0000000000000000 +@cb 0000000000000000 +@cc 0000000000000000 +@cd 0000000000000000 +@ce 0000000000000000 +@cf 0000000000000000 +@d0 0000000000000000 +@d1 0000000000000000 +@d2 0000000000000000 +@d3 0000000000000000 +@d4 0000000000000000 +@d5 0000000000000000 +@d6 0000000000000000 +@d7 0000000000000000 +@d8 0000000000000000 +@d9 0000000000000000 +@da 0000000000000000 +@db 0000000000000000 +@dc 0000000000000000 +@dd 0000000000000000 +@de 0000000000000000 +@df 0000000000000000 +@e0 0000000000000000 +@e1 0000000000000000 +@e2 0000000000000000 +@e3 0000000000000000 +@e4 0000000000000000 +@e5 0000000000000000 +@e6 0000000000000000 +@e7 0000000000000000 +@e8 0000000000000000 +@e9 0000000000000000 +@ea 0000000000000000 +@eb 0000000000000000 +@ec 0000000000000000 +@ed 0000000000000000 +@ee 0000000000000000 +@ef 0000000000000000 +@f0 0000000000000000 +@f1 0000000000000000 +@f2 0000000000000000 +@f3 0000000000000000 +@f4 0000000000000000 +@f5 0000000000000000 +@f6 0000000000000000 +@f7 0000000000000000 +@f8 0000000000000000 +@f9 0000000000000000 +@fa 0000000000000000 +@fb 0000000000000000 +@fc 0000000000000000 +@fd 0000000000000000 +@fe 0000000000000000 +@ff 0000000000000000 diff --git a/mem/data_lab8_check.txt b/mem/data_lab8_check.txt new file mode 100644 index 0000000..5c1ac68 --- /dev/null +++ b/mem/data_lab8_check.txt @@ -0,0 +1,256 @@ +@00 1101000000001111 +@01 0110000000000000 +@02 1101000100000000 +@03 1101001000000000 +@04 1101001100010000 +@05 1101010000000001 +@06 1010001110100001 +@07 0110010110100000 +@08 1010001001000101 +@09 1010000100100100 +@0a 1010100100000000 +@0b 0010001111111010 +@0c 1101001100010100 +@0d 1000001101000000 +@0e 1110000000000000 +@0f 0000000000000100 +@10 0000000000110010 +@11 0000000011001000 +@12 0000000001100100 +@13 0000000111110100 +@14 1011101011011101 +@15 0000000000000000 +@16 0000000000000000 +@17 0000000000000000 +@18 0000000000000000 +@19 0000000000000000 +@1a 0000000000000000 +@1b 0000000000000000 +@1c 0000000000000000 +@1d 0000000000000000 +@1e 0000000000000000 +@1f 0000000000000000 +@20 0000000000000000 +@21 0000000000000000 +@22 0000000000000000 +@23 0000000000000000 +@24 0000000000000000 +@25 0000000000000000 +@26 0000000000000000 +@27 0000000000000000 +@28 0000000000000000 +@29 0000000000000000 +@2a 0000000000000000 +@2b 0000000000000000 +@2c 0000000000000000 +@2d 0000000000000000 +@2e 0000000000000000 +@2f 0000000000000000 +@30 0000000000000000 +@31 0000000000000000 +@32 0000000000000000 +@33 0000000000000000 +@34 0000000000000000 +@35 0000000000000000 +@36 0000000000000000 +@37 0000000000000000 +@38 0000000000000000 +@39 0000000000000000 +@3a 0000000000000000 +@3b 0000000000000000 +@3c 0000000000000000 +@3d 0000000000000000 +@3e 0000000000000000 +@3f 0000000000000000 +@40 0000000000000000 +@41 0000000000000000 +@42 0000000000000000 +@43 0000000000000000 +@44 0000000000000000 +@45 0000000000000000 +@46 0000000000000000 +@47 0000000000000000 +@48 0000000000000000 +@49 0000000000000000 +@4a 0000000000000000 +@4b 0000000000000000 +@4c 0000000000000000 +@4d 0000000000000000 +@4e 0000000000000000 +@4f 0000000000000000 +@50 0000000000000000 +@51 0000000000000000 +@52 0000000000000000 +@53 0000000000000000 +@54 0000000000000000 +@55 0000000000000000 +@56 0000000000000000 +@57 0000000000000000 +@58 0000000000000000 +@59 0000000000000000 +@5a 0000000000000000 +@5b 0000000000000000 +@5c 0000000000000000 +@5d 0000000000000000 +@5e 0000000000000000 +@5f 0000000000000000 +@60 0000000000000000 +@61 0000000000000000 +@62 0000000000000000 +@63 0000000000000000 +@64 0000000000000000 +@65 0000000000000000 +@66 0000000000000000 +@67 0000000000000000 +@68 0000000000000000 +@69 0000000000000000 +@6a 0000000000000000 +@6b 0000000000000000 +@6c 0000000000000000 +@6d 0000000000000000 +@6e 0000000000000000 +@6f 0000000000000000 +@70 0000000000000000 +@71 0000000000000000 +@72 0000000000000000 +@73 0000000000000000 +@74 0000000000000000 +@75 0000000000000000 +@76 0000000000000000 +@77 0000000000000000 +@78 0000000000000000 +@79 0000000000000000 +@7a 0000000000000000 +@7b 0000000000000000 +@7c 0000000000000000 +@7d 0000000000000000 +@7e 0000000000000000 +@7f 0000000000000000 +@80 0000000000000000 +@81 0000000000000000 +@82 0000000000000000 +@83 0000000000000000 +@84 0000000000000000 +@85 0000000000000000 +@86 0000000000000000 +@87 0000000000000000 +@88 0000000000000000 +@89 0000000000000000 +@8a 0000000000000000 +@8b 0000000000000000 +@8c 0000000000000000 +@8d 0000000000000000 +@8e 0000000000000000 +@8f 0000000000000000 +@90 0000000000000000 +@91 0000000000000000 +@92 0000000000000000 +@93 0000000000000000 +@94 0000000000000000 +@95 0000000000000000 +@96 0000000000000000 +@97 0000000000000000 +@98 0000000000000000 +@99 0000000000000000 +@9a 0000000000000000 +@9b 0000000000000000 +@9c 0000000000000000 +@9d 0000000000000000 +@9e 0000000000000000 +@9f 0000000000000000 +@a0 0000000000000000 +@a1 0000000000000000 +@a2 0000000000000000 +@a3 0000000000000000 +@a4 0000000000000000 +@a5 0000000000000000 +@a6 0000000000000000 +@a7 0000000000000000 +@a8 0000000000000000 +@a9 0000000000000000 +@aa 0000000000000000 +@ab 0000000000000000 +@ac 0000000000000000 +@ad 0000000000000000 +@ae 0000000000000000 +@af 0000000000000000 +@b0 0000000000000000 +@b1 0000000000000000 +@b2 0000000000000000 +@b3 0000000000000000 +@b4 0000000000000000 +@b5 0000000000000000 +@b6 0000000000000000 +@b7 0000000000000000 +@b8 0000000000000000 +@b9 0000000000000000 +@ba 0000000000000000 +@bb 0000000000000000 +@bc 0000000000000000 +@bd 0000000000000000 +@be 0000000000000000 +@bf 0000000000000000 +@c0 0000000000000000 +@c1 0000000000000000 +@c2 0000000000000000 +@c3 0000000000000000 +@c4 0000000000000000 +@c5 0000000000000000 +@c6 0000000000000000 +@c7 0000000000000000 +@c8 0000000000000000 +@c9 0000000000000000 +@ca 0000000000000000 +@cb 0000000000000000 +@cc 0000000000000000 +@cd 0000000000000000 +@ce 0000000000000000 +@cf 0000000000000000 +@d0 0000000000000000 +@d1 0000000000000000 +@d2 0000000000000000 +@d3 0000000000000000 +@d4 0000000000000000 +@d5 0000000000000000 +@d6 0000000000000000 +@d7 0000000000000000 +@d8 0000000000000000 +@d9 0000000000000000 +@da 0000000000000000 +@db 0000000000000000 +@dc 0000000000000000 +@dd 0000000000000000 +@de 0000000000000000 +@df 0000000000000000 +@e0 0000000000000000 +@e1 0000000000000000 +@e2 0000000000000000 +@e3 0000000000000000 +@e4 0000000000000000 +@e5 0000000000000000 +@e6 0000000000000000 +@e7 0000000000000000 +@e8 0000000000000000 +@e9 0000000000000000 +@ea 0000000000000000 +@eb 0000000000000000 +@ec 0000000000000000 +@ed 0000000000000000 +@ee 0000000000000000 +@ef 0000000000000000 +@f0 0000000000000000 +@f1 0000000000000000 +@f2 0000000000000000 +@f3 0000000000000000 +@f4 0000000000000000 +@f5 0000000000000000 +@f6 0000000000000000 +@f7 0000000000000000 +@f8 0000000000000000 +@f9 0000000000000000 +@fa 0000000000000000 +@fb 0000000000000000 +@fc 0000000000000000 +@fd 0000000000000000 +@fe 0000000000000000 +@ff 0000000000000000 diff --git a/mem/data_lab8_stage2.txt b/mem/data_lab8_stage2.txt new file mode 100644 index 0000000..9c49489 --- /dev/null +++ b/mem/data_lab8_stage2.txt @@ -0,0 +1,256 @@ +@00 1101011000011000 +@01 0110011011000000 +@02 1101010000011001 +@03 1101001100000000 +@04 1000010001100000 +@05 1101000000000001 +@06 1101000100000101 +@07 1101001000001001 +@08 1101001100010100 +@09 0101111100000010 +@0a 1000010000000000 +@0b 1110000000000000 +@0c 1000011010000000 +@0d 1000011010111111 +@0e 1010000010000001 +@0f 1010001010100011 +@10 1011100010100101 +@11 1010010010000101 +@12 1101010100000001 +@13 1010010010000101 +@14 1100000000000100 +@15 0110011010111111 +@16 0110011010000000 +@17 0100000011100000 +@18 0000000011111111 +@19 1100110011001100 +@1a 0000000000000000 +@1b 0000000000000000 +@1c 0000000000000000 +@1d 0000000000000000 +@1e 0000000000000000 +@1f 0000000000000000 +@20 0000000000000000 +@21 0000000000000000 +@22 0000000000000000 +@23 0000000000000000 +@24 0000000000000000 +@25 0000000000000000 +@26 0000000000000000 +@27 0000000000000000 +@28 0000000000000000 +@29 0000000000000000 +@2a 0000000000000000 +@2b 0000000000000000 +@2c 0000000000000000 +@2d 0000000000000000 +@2e 0000000000000000 +@2f 0000000000000000 +@30 0000000000000000 +@31 0000000000000000 +@32 0000000000000000 +@33 0000000000000000 +@34 0000000000000000 +@35 0000000000000000 +@36 0000000000000000 +@37 0000000000000000 +@38 0000000000000000 +@39 0000000000000000 +@3a 0000000000000000 +@3b 0000000000000000 +@3c 0000000000000000 +@3d 0000000000000000 +@3e 0000000000000000 +@3f 0000000000000000 +@40 0000000000000000 +@41 0000000000000000 +@42 0000000000000000 +@43 0000000000000000 +@44 0000000000000000 +@45 0000000000000000 +@46 0000000000000000 +@47 0000000000000000 +@48 0000000000000000 +@49 0000000000000000 +@4a 0000000000000000 +@4b 0000000000000000 +@4c 0000000000000000 +@4d 0000000000000000 +@4e 0000000000000000 +@4f 0000000000000000 +@50 0000000000000000 +@51 0000000000000000 +@52 0000000000000000 +@53 0000000000000000 +@54 0000000000000000 +@55 0000000000000000 +@56 0000000000000000 +@57 0000000000000000 +@58 0000000000000000 +@59 0000000000000000 +@5a 0000000000000000 +@5b 0000000000000000 +@5c 0000000000000000 +@5d 0000000000000000 +@5e 0000000000000000 +@5f 0000000000000000 +@60 0000000000000000 +@61 0000000000000000 +@62 0000000000000000 +@63 0000000000000000 +@64 0000000000000000 +@65 0000000000000000 +@66 0000000000000000 +@67 0000000000000000 +@68 0000000000000000 +@69 0000000000000000 +@6a 0000000000000000 +@6b 0000000000000000 +@6c 0000000000000000 +@6d 0000000000000000 +@6e 0000000000000000 +@6f 0000000000000000 +@70 0000000000000000 +@71 0000000000000000 +@72 0000000000000000 +@73 0000000000000000 +@74 0000000000000000 +@75 0000000000000000 +@76 0000000000000000 +@77 0000000000000000 +@78 0000000000000000 +@79 0000000000000000 +@7a 0000000000000000 +@7b 0000000000000000 +@7c 0000000000000000 +@7d 0000000000000000 +@7e 0000000000000000 +@7f 0000000000000000 +@80 0000000000000000 +@81 0000000000000000 +@82 0000000000000000 +@83 0000000000000000 +@84 0000000000000000 +@85 0000000000000000 +@86 0000000000000000 +@87 0000000000000000 +@88 0000000000000000 +@89 0000000000000000 +@8a 0000000000000000 +@8b 0000000000000000 +@8c 0000000000000000 +@8d 0000000000000000 +@8e 0000000000000000 +@8f 0000000000000000 +@90 0000000000000000 +@91 0000000000000000 +@92 0000000000000000 +@93 0000000000000000 +@94 0000000000000000 +@95 0000000000000000 +@96 0000000000000000 +@97 0000000000000000 +@98 0000000000000000 +@99 0000000000000000 +@9a 0000000000000000 +@9b 0000000000000000 +@9c 0000000000000000 +@9d 0000000000000000 +@9e 0000000000000000 +@9f 0000000000000000 +@a0 0000000000000000 +@a1 0000000000000000 +@a2 0000000000000000 +@a3 0000000000000000 +@a4 0000000000000000 +@a5 0000000000000000 +@a6 0000000000000000 +@a7 0000000000000000 +@a8 0000000000000000 +@a9 0000000000000000 +@aa 0000000000000000 +@ab 0000000000000000 +@ac 0000000000000000 +@ad 0000000000000000 +@ae 0000000000000000 +@af 0000000000000000 +@b0 0000000000000000 +@b1 0000000000000000 +@b2 0000000000000000 +@b3 0000000000000000 +@b4 0000000000000000 +@b5 0000000000000000 +@b6 0000000000000000 +@b7 0000000000000000 +@b8 0000000000000000 +@b9 0000000000000000 +@ba 0000000000000000 +@bb 0000000000000000 +@bc 0000000000000000 +@bd 0000000000000000 +@be 0000000000000000 +@bf 0000000000000000 +@c0 0000000000000000 +@c1 0000000000000000 +@c2 0000000000000000 +@c3 0000000000000000 +@c4 0000000000000000 +@c5 0000000000000000 +@c6 0000000000000000 +@c7 0000000000000000 +@c8 0000000000000000 +@c9 0000000000000000 +@ca 0000000000000000 +@cb 0000000000000000 +@cc 0000000000000000 +@cd 0000000000000000 +@ce 0000000000000000 +@cf 0000000000000000 +@d0 0000000000000000 +@d1 0000000000000000 +@d2 0000000000000000 +@d3 0000000000000000 +@d4 0000000000000000 +@d5 0000000000000000 +@d6 0000000000000000 +@d7 0000000000000000 +@d8 0000000000000000 +@d9 0000000000000000 +@da 0000000000000000 +@db 0000000000000000 +@dc 0000000000000000 +@dd 0000000000000000 +@de 0000000000000000 +@df 0000000000000000 +@e0 0000000000000000 +@e1 0000000000000000 +@e2 0000000000000000 +@e3 0000000000000000 +@e4 0000000000000000 +@e5 0000000000000000 +@e6 0000000000000000 +@e7 0000000000000000 +@e8 0000000000000000 +@e9 0000000000000000 +@ea 0000000000000000 +@eb 0000000000000000 +@ec 0000000000000000 +@ed 0000000000000000 +@ee 0000000000000000 +@ef 0000000000000000 +@f0 0000000000000000 +@f1 0000000000000000 +@f2 0000000000000000 +@f3 0000000000000000 +@f4 0000000000000000 +@f5 0000000000000000 +@f6 0000000000000000 +@f7 0000000000000000 +@f8 0000000000000000 +@f9 0000000000000000 +@fa 0000000000000000 +@fb 0000000000000000 +@fc 0000000000000000 +@fd 0000000000000000 +@fe 0000000000000000 +@ff 0000000000000000 diff --git a/regfile.sv b/regfile.sv deleted file mode 100644 index 8237b26..0000000 --- a/regfile.sv +++ /dev/null @@ -1,45 +0,0 @@ -module regfile(data_in,writenum,write,readnum,clk,data_out);
- input [15:0] data_in;
- input [2:0] writenum, readnum;
- input write, clk;
- output reg [15:0] data_out;
-
- // This file is made explicit and long for easy readability
- // e.g
- // The always_comb can have only one case (readnum to data_out change)
- // The always_ff in turn will only have one if and one case (write and writenum to R0-R7)
- // make file more efficient
-
- reg [15:0] R0, R1, R2, R3, R4, R5, R6, R7;
-
- always_comb begin
- //read num for data_out
- case (readnum)
- 3'b000: data_out = R0;
- 3'b001: data_out = R1;
- 3'b010: data_out = R2;
- 3'b011: data_out = R3;
- 3'b100: data_out = R4;
- 3'b101: data_out = R5;
- 3'b110: data_out = R6;
- 3'b111: data_out = R7;
- endcase
- end
-
- always_ff @(posedge clk) begin
- if (write) begin //only load into register if write is on = 1
- case (writenum)
- // Check load select and put data_in into R0-7 depending
- 3'b000: R0 <= data_in;
- 3'b001: R1 <= data_in;
- 3'b010: R2 <= data_in;
- 3'b011: R3 <= data_in;
- 3'b100: R4 <= data_in;
- 3'b101: R5 <= data_in;
- 3'b110: R6 <= data_in;
- 3'b111: R7 <= data_in;
- endcase
- end
- end
-
-endmodule
\ No newline at end of file diff --git a/shifter.sv b/shifter.sv deleted file mode 100644 index da6fd77..0000000 --- a/shifter.sv +++ /dev/null @@ -1,18 +0,0 @@ -module shifter(in,shift,sout);
- input [15:0] in;
- input [1:0] shift;
- output reg [15:0] sout;
-
- always_comb begin
- case (shift)
- //no shift
- 2'b00: sout = in;
- 2'b01: sout = in << 1; //left bit shift
- 2'b10: sout = in >> 1; //right bit shift
- 2'b11: begin
- sout = in >> 1;
- sout[15] = sout[14]; //in[15] copied to to MSB after right bit shift
- end
- endcase
- end
-endmodule
\ No newline at end of file diff --git a/src/alu.sv b/src/alu.sv new file mode 100644 index 0000000..c6d00bd --- /dev/null +++ b/src/alu.sv @@ -0,0 +1,17 @@ +module ALU(Ain, Bin, op, out, status); + input [1:0] op; + input [15:0] Ain, Bin; + output [2:0] status; + output reg [15:0] out; + + assign status[2] = out[15]; + assign status[1] = (out[15] ^ Ain[15]) & ~(out[15] ^ Bin[15]); + assign status[0] = (out == 0); + + always_comb case (op) + 2'b00: out = Ain + Bin; + 2'b01: out = Ain - Bin; + 2'b10: out = Ain & Bin; + 2'b11: out = ~Bin; + endcase +endmodule: ALU diff --git a/src/cpu.sv b/src/cpu.sv new file mode 100644 index 0000000..0efcd6d --- /dev/null +++ b/src/cpu.sv @@ -0,0 +1,94 @@ +module cpu(clk, reset, mem_data, mem_cmd, mem_addr, out, N, V, Z, halt); + input clk, reset; + input [15:0] mem_data; + output N, V, Z, halt; + output [1:0] mem_cmd; + output [15:0] out; + output reg [8:0] mem_addr; + + wire pc_reset, pc_load, ir_load, addr_sel, write, loada, loadb, loadc, + loads, loadm, asel, bsel, csel; + wire [1:0] pc_sel, op, sh; + wire [2:0] opcode, cond, Rn, Rd, Rm, reg_w_sel, reg_a_sel, reg_b_sel; + wire [3:0] vsel; + wire [8:0] PC, data_address; + wire [15:0] instruction, sximm5, sximm8; + reg [2:0] reg_w, reg_a, reg_b; + reg [8:0] pc_next; + + register #(16) U0(mem_data, ir_load, clk, instruction); + register #(9) U1(pc_next, pc_load, clk, PC); + + statemachine FSM(clk, reset, opcode, op, pc_reset, pc_load, pc_sel, + ir_load, addr_sel, mem_cmd, reg_w_sel, reg_a_sel, + reg_b_sel, write, loada, loadb, loadc, loads, loadm, asel, bsel, + csel, vsel, halt); + + datapath DP(clk, reg_w, reg_a, reg_b, write, loada, loadb, loadc, loads, + loadm, op, sh, asel, bsel, csel, vsel, sximm5, sximm8, + mem_data, PC, N, V, Z, out, data_address); + + assign mem_addr = addr_sel ? PC : data_address; + + /* Instruction decoder. */ + assign {opcode, op, Rn, Rd, sh, Rm} = instruction; + assign cond = instruction[10:8]; + assign sximm8 = {{8{instruction[7]}}, instruction[7:0]}; + assign sximm5 = {{11{instruction[4]}}, instruction[4:0]}; + + always_comb begin + /* Selector for REGFILE read/write registers. */ + case (reg_w_sel) + 3'b100: reg_w = Rn; + 3'b010: reg_w = Rd; + 3'b001: reg_w = Rm; + default: reg_w = 3'bzzz; + endcase + case (reg_a_sel) + 3'b100: reg_a = Rn; + 3'b010: reg_a = Rd; + 3'b001: reg_a = Rm; + default: reg_a = 3'bzzz; + endcase + case (reg_b_sel) + 3'b100: reg_b = Rn; + 3'b010: reg_b = Rd; + 3'b001: reg_b = Rm; + default: reg_b = 3'bzzz; + endcase + + /* Branching logic. */ + casex ({pc_reset, pc_sel}) + 3'b1_xx: + pc_next = 9'b0; + 3'b0_01: begin + pc_next = PC; + case ({opcode, cond}) + /* B. */ + 6'b001_000: + pc_next = PC + sximm8[8:0]; + /* BEQ. */ + 6'b001_001: if (Z) + pc_next = PC + sximm8[8:0]; + /* BNE. */ + 6'b001_010: if (~Z) + pc_next = PC + sximm8[8:0]; + /* BLT. */ + 6'b001_011: if (N !== V) + pc_next = PC + sximm8[8:0]; + /* BLE. */ + 6'b001_100: if (N !== V | Z) + pc_next = PC + sximm8[8:0]; + endcase + end + /* BX, BLX. */ + 3'b0_10: + pc_next = out; + /* BL. */ + 3'b0_11: + pc_next = PC + sximm8[8:0]; + /* Next address in memory. */ + default: pc_next = PC + 1; + endcase + end +endmodule: cpu diff --git a/src/datapath.sv b/src/datapath.sv new file mode 100644 index 0000000..f0e85a5 --- /dev/null +++ b/src/datapath.sv @@ -0,0 +1,38 @@ +module datapath(clk, reg_w, reg_a, reg_b, write, loada, loadb, loadc, loads, + loadm, op, shift, asel, bsel, csel, vsel, sximm5, sximm8, + mdata, PC, N, V, Z, datapath_out, data_address); + input clk, write, loada, loadb, loadc, loads, loadm, asel, bsel, csel; + input [1:0] op, shift; + input [2:0] reg_w, reg_a, reg_b; + input [3:0] vsel; + input [8:0] PC; + input [15:0] sximm8, sximm5, mdata; + output N, V, Z; + output [8:0] data_address; + output reg [15:0] datapath_out; + + wire [2:0] status; + wire [15:0] out_a, out_b, aout, bout, sout, ain, bin, out; + reg [15:0] data_in; + + regfile REGFILE(clk, data_in, write, reg_w, reg_a, reg_b, out_a, out_b); + shifter U0(bout, shift, sout); + ALU U1(ain, bin, op, out, status); + register #(16) REG_A(out_a, loada, clk, aout); + register #(16) REG_B(out_b, loadb, clk, bout); + register #(16) REG_C((csel ? out_b : out), loadc, clk, datapath_out); + register #(9) REG_M(out[8:0], loadm, clk, data_address); + register #(3) REG_S(status, loads, clk, {N, V, Z}); + + assign ain = asel ? 16'b0 : aout; + assign bin = bsel ? sximm5 : sout; + + /* One-hot signal: vsel. */ + always_comb begin + data_in = {16{1'bz}}; + if (vsel[0]) data_in = datapath_out; + if (vsel[1]) data_in = mdata; + if (vsel[2]) data_in = sximm8; + if (vsel[3]) data_in = {7'b0, PC}; + end +endmodule: datapath diff --git a/src/lab7bonus_top.sv b/src/lab7bonus_top.sv new file mode 100644 index 0000000..2a9e805 --- /dev/null +++ b/src/lab7bonus_top.sv @@ -0,0 +1,79 @@ +`define M_NOP 2'b00 +`define M_READ 2'b10 +`define M_WRITE 2'b01 + +module lab7bonus_top(KEY, SW, LEDR, HEX0, HEX1, HEX2, HEX3, HEX4, HEX5, CLOCK_50); + input CLOCK_50; + input [3:0] KEY; + input [9:0] SW; + output [6:0] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5; + output [9:0] LEDR; + + wire clk, write, N, V, Z, halt; + wire [1:0] mem_cmd; + wire [8:0] mem_addr; + wire [15:0] din, dout, mem_data; + + ram #(16, 8) MEM(clk, mem_addr[7:0], write, din, dout); + cpu CPU(clk, reset, mem_data, mem_cmd, mem_addr, din, N, V, Z, halt); + + disp U0(din[3:0], HEX0); + disp U1(din[7:4], HEX1); + disp U2(din[11:8], HEX2); + disp U3(din[15:12], HEX3); + disp U4({1'b0, N, V, Z}, HEX4); + + assign clk = CLOCK_50; + assign reset = ~KEY[1]; + assign LEDR[8] = halt; + + assign mem_data = (mem_cmd == `M_READ & ~mem_addr[8]) + ? dout : {16{1'bz}}; + assign write = mem_cmd == `M_WRITE & ~mem_addr[8]; +endmodule: lab7bonus_top + +module ram(clk, addr, write, din, dout); + parameter data_width = 32; + parameter addr_width = 4; + parameter filename = "data.txt"; + + input clk; + input [addr_width-1:0] addr; + input write; + input [data_width-1:0] din; + output [data_width-1:0] dout; + reg [data_width-1:0] dout; + + reg [data_width-1:0] mem [2**addr_width-1:0]; + + initial $readmemb(filename, mem); + + always @ (posedge clk) begin + if (write) mem[addr] <= din; + dout <= mem[addr]; + end +endmodule: ram + +module disp(in, out); + input [3:0] in; + output reg [6:0] out; + + always_comb case (in) + 4'h0: out = 7'b1000000; + 4'h1: out = 7'b1111001; + 4'h2: out = 7'b0100100; + 4'h3: out = 7'b0110000; + 4'h4: out = 7'b0011001; + 4'h5: out = 7'b0010010; + 4'h6: out = 7'b0000010; + 4'h7: out = 7'b1111000; + 4'h8: out = 7'b0000000; + 4'h9: out = 7'b0010000; + 4'ha: out = 7'b0001000; + 4'hb: out = 7'b0000011; + 4'hc: out = 7'b0100111; + 4'hd: out = 7'b0100001; + 4'he: out = 7'b0000110; + 4'hf: out = 7'b0001110; + endcase +endmodule: disp diff --git a/src/regfile.sv b/src/regfile.sv new file mode 100644 index 0000000..7c53807 --- /dev/null +++ b/src/regfile.sv @@ -0,0 +1,54 @@ +module regfile(clk, data_in, write, reg_w, reg_a, reg_b, out_a, out_b); + input clk, write; + input [2:0] reg_w, reg_a, reg_b; + input [15:0] data_in; + output reg [15:0] out_a, out_b; + + wire [7:0] load; + wire [15:0] R0, R1, R2, R3, R4, R5, R6, R7; + + register #(16) U0(data_in, load[0], clk, R0); + register #(16) U1(data_in, load[1], clk, R1); + register #(16) U2(data_in, load[2], clk, R2); + register #(16) U3(data_in, load[3], clk, R3); + register #(16) U4(data_in, load[4], clk, R4); + register #(16) U5(data_in, load[5], clk, R5); + register #(16) U6(data_in, load[6], clk, R6); + register #(16) U7(data_in, load[7], clk, R7); + + assign load = {8{write}} & (8'b1 << reg_w); + + always_comb begin + case (reg_a) + 0: out_a = R0; + 1: out_a = R1; + 2: out_a = R2; + 3: out_a = R3; + 4: out_a = R4; + 5: out_a = R5; + 6: out_a = R6; + 7: out_a = R7; + endcase + + case (reg_b) + 0: out_b = R0; + 1: out_b = R1; + 2: out_b = R2; + 3: out_b = R3; + 4: out_b = R4; + 5: out_b = R5; + 6: out_b = R6; + 7: out_b = R7; + endcase + end +endmodule: regfile + +module register(in, load, clk, out); + parameter n = 1; + input [n-1:0] in; + input load, clk; + output reg [n-1:0] out; + + always_ff @(posedge clk) + if (load) out = in; +endmodule: register diff --git a/src/shifter.sv b/src/shifter.sv new file mode 100644 index 0000000..66e5c74 --- /dev/null +++ b/src/shifter.sv @@ -0,0 +1,12 @@ +module shifter(in, shift, sout); + input [1:0] shift; + input [15:0] in; + output reg [15:0] sout; + + always_comb case (shift) + 2'b00: sout = in; + 2'b01: sout = {in[14:0], 1'b0}; + 2'b10: sout = {1'b0, in[15:1]}; + 2'b11: sout = {in[15], in[15:1]}; + endcase +endmodule: shifter diff --git a/src/statemachine.sv b/src/statemachine.sv new file mode 100644 index 0000000..1a5beb1 --- /dev/null +++ b/src/statemachine.sv @@ -0,0 +1,246 @@ +`define STATE_RESET 3'b000 +`define STATE_HALT 3'b001 +`define STATE_IF 3'b010 +`define STATE_DECODE 3'b011 +`define STATE_EXEC 3'b100 +`define STATE_MEM 3'b101 +`define STATE_WRITEBACK 3'b110 + +module statemachine(clk, reset, opcode, op, pc_reset, pc_load, pc_sel, ir_load, + addr_sel, mem_cmd, reg_w_sel, reg_a_sel, reg_b_sel, write, + loada, loadb, loadc, loads, loadm, asel, bsel, csel, vsel, + halt); + input clk, reset; + input [1:0] op; + input [2:0] opcode; + output reg pc_reset, pc_load, ir_load, addr_sel, write, loada, loadb, + loadc, loads, loadm, asel, bsel, csel, halt; + output reg [1:0] pc_sel, mem_cmd; + output reg [2:0] reg_w_sel, reg_a_sel, reg_b_sel; + output reg [3:0] vsel; + + reg [3:0] state; + + always_comb begin + {pc_reset, pc_load, pc_sel, ir_load, addr_sel, mem_cmd, + reg_w_sel, reg_a_sel, reg_b_sel, write, loada, loadb, + loadc, loads, loadm, asel, bsel, csel, vsel, halt} + = 31'b0; + + casex ({state, opcode, op}) + /* Reset state. */ + {`STATE_RESET, 5'bxxx_xx}: + {pc_reset, pc_load, addr_sel, mem_cmd} + = 5'b111_10; + + /* Instruction fetch. */ + {`STATE_IF, 5'bxxx_xx}: + {pc_load, ir_load, addr_sel, mem_cmd} = 5'b111_10; + + /* MOV immediate to register. */ + {`STATE_DECODE, 5'b110_10}: + {addr_sel, mem_cmd, reg_w_sel, write, vsel} + = 11'b1_10_100_1_0100; + + /* MOV register to register. */ + {`STATE_DECODE, 5'b110_00}: + {reg_b_sel, loadb} = 4'b001_1; + {`STATE_EXEC, 5'b110_00}: + {loadc, asel} = 2'b11; + {`STATE_WRITEBACK, 5'b110_00}: + {addr_sel, mem_cmd, reg_w_sel, write, vsel} + = 11'b1_10_010_1_0001; + + /* General ALU operations. */ + {`STATE_DECODE, 5'b101_xx}: + {reg_a_sel, reg_b_sel, loada, loadb} = 8'b100_001_11; + + /* ADD. */ + {`STATE_EXEC, 5'b101_00}: + loadc = 1'b1; + {`STATE_WRITEBACK, 5'b101_00}: + {addr_sel, mem_cmd, reg_w_sel, write, vsel} + = 11'b1_10_010_1_0001; + + /* CMP. */ + {`STATE_EXEC, 5'b101_01}: + {addr_sel, mem_cmd, loads} = 4'b1_10_1; + + /* AND. */ + {`STATE_EXEC, 5'b101_10}: + loadc = 1'b1; + {`STATE_WRITEBACK, 5'b101_10}: + {addr_sel, mem_cmd, reg_w_sel, write, vsel} + = 11'b1_10_010_1_0001; + + /* MVN. */ + {`STATE_EXEC, 5'b101_11}: + loadc = 1'b1; + {`STATE_WRITEBACK, 5'b101_11}: + {addr_sel, mem_cmd, reg_w_sel, write, vsel} + = 11'b1_10_010_1_0001; + + /* LDR. */ + {`STATE_DECODE, 5'b011_xx}: + {reg_a_sel, loada} = 4'b100_1; + {`STATE_EXEC, 5'b011_xx}: + {loadm, bsel} = 2'b11; + {`STATE_MEM, 5'b011_xx}: + mem_cmd = 2'b10; + {`STATE_WRITEBACK, 5'b011_xx}: + {addr_sel, mem_cmd, reg_w_sel, write, vsel} + = 11'b1_10_010_1_0010; + + /* STR. */ + {`STATE_DECODE, 5'b100_xx}: + {reg_a_sel, reg_b_sel, csel, loada, loadc} + = 9'b100_010_111; + {`STATE_EXEC, 5'b100_xx}: + {loadm, bsel} = 2'b11; + {`STATE_MEM, 5'b100_xx}: + mem_cmd = 2'b01; + {`STATE_WRITEBACK, 5'b100_xx}: + {addr_sel, mem_cmd} = 3'b1_10; + + /* B, BEQ, BNE, BLT, BLE. */ + {`STATE_DECODE, 5'b001_xx}: + {pc_load, pc_sel} = 3'b1_01; + {`STATE_EXEC, 5'b001_xx}: + {addr_sel, mem_cmd} = 3'b1_10; + + /* BL. */ + {`STATE_DECODE, 5'b010_11}: + {pc_load, pc_sel, reg_w_sel, write, vsel} + = 11'b1_11_100_1_1000; + {`STATE_EXEC, 5'b010_11}: + {addr_sel, mem_cmd} = 3'b1_10; + + /* BX, BLX. */ + {`STATE_DECODE, 5'b010_xx}: + {reg_b_sel, loadc, csel} = 5'b010_11; + + /* BX. */ + {`STATE_EXEC, 5'b010_00}: + {pc_load, pc_sel} = 3'b1_10; + {`STATE_WRITEBACK, 5'b010_00}: + {addr_sel, mem_cmd} = 3'b1_10; + + /* BLX. */ + {`STATE_EXEC, 5'b010_10}: + {pc_load, pc_sel, reg_w_sel, write, vsel} + = 11'b1_10_100_1_1000; + {`STATE_WRITEBACK, 5'b010_10}: + {addr_sel, mem_cmd} + = 3'b1_10; + + {`STATE_HALT, 5'bxxx_xx}: + halt = 1'b1; + + default: begin end + endcase + end + + always_ff @(posedge clk) casex ({reset, state, opcode, op}) + /* Reset. */ + 10'b1_xxxx_xxx_xx: + state <= `STATE_RESET; + {1'b0, `STATE_RESET, 5'bxxx_xx}: + state <= `STATE_IF; + + /* Beginning of instruction cycle. */ + {1'b0, `STATE_IF, 5'bxxx_xx}: + state <= `STATE_DECODE; + + /* HALT. */ + {1'b0, `STATE_DECODE, 5'b111_xx}: + state <= `STATE_HALT; + {1'b0, `STATE_HALT, 5'bxxx_xx}: + state <= `STATE_HALT; + + /* MOV immediate to register. */ + {1'b0, `STATE_DECODE, 5'b110_10}: + state <= `STATE_IF; + + /* MOV register to register. */ + {1'b0, `STATE_DECODE, 5'b110_00}: + state <= `STATE_EXEC; + {1'b0, `STATE_EXEC, 5'b110_00}: + state <= `STATE_WRITEBACK; + {1'b0, `STATE_WRITEBACK, 5'b110_00}: + state <= `STATE_IF; + + /* ADD. */ + {1'b0, `STATE_DECODE, 5'b101_00}: + state <= `STATE_EXEC; + {1'b0, `STATE_EXEC, 5'b101_00}: + state <= `STATE_WRITEBACK; + {1'b0, `STATE_WRITEBACK, 5'b101_00}: + state <= `STATE_IF; + + /* CMP. */ + {1'b0, `STATE_DECODE, 5'b101_01}: + state <= `STATE_EXEC; + {1'b0, `STATE_EXEC, 5'b101_01}: + state <= `STATE_IF; + + /* AND. */ + {1'b0, `STATE_DECODE, 5'b101_10}: + state <= `STATE_EXEC; + {1'b0, `STATE_EXEC, 5'b101_10}: + state <= `STATE_WRITEBACK; + {1'b0, `STATE_WRITEBACK, 5'b101_10}: + state <= `STATE_IF; + + /* MVN. */ + {1'b0, `STATE_DECODE, 5'b101_11}: + state <= `STATE_EXEC; + {1'b0, `STATE_EXEC, 5'b101_11}: + state <= `STATE_WRITEBACK; + {1'b0, `STATE_WRITEBACK, 5'b101_11}: + state <= `STATE_IF; + + /* LDR. */ + {1'b0, `STATE_DECODE, 5'b011_xx}: + state <= `STATE_EXEC; + {1'b0, `STATE_EXEC, 5'b011_xx}: + state <= `STATE_MEM; + {1'b0, `STATE_MEM, 5'b011_xx}: + state <= `STATE_WRITEBACK; + {1'b0, `STATE_WRITEBACK, 5'b011_xx}: + state <= `STATE_IF; + + /* STR. */ + {1'b0, `STATE_DECODE, 5'b100_xx}: + state <= `STATE_EXEC; + {1'b0, `STATE_EXEC, 5'b100_xx}: + state <= `STATE_MEM; + {1'b0, `STATE_MEM, 5'b100_xx}: + state <= `STATE_WRITEBACK; + {1'b0, `STATE_WRITEBACK, 5'b100_xx}: + state <= `STATE_IF; + + /* B, BEQ, BNE, BLT, BLE. */ + {1'b0, `STATE_DECODE, 5'b001_xx}: + state <= `STATE_EXEC; + {1'b0, `STATE_EXEC, 5'b001_xx}: + state <= `STATE_IF; + + /* BL. */ + {1'b0, `STATE_DECODE, 5'b010_11}: + state <= `STATE_EXEC; + {1'b0, `STATE_EXEC, 5'b010_11}: + state <= `STATE_IF; + + /* BX, BLX. */ + {1'b0, `STATE_DECODE, 5'b010_xx}: + state <= `STATE_EXEC; + {1'b0, `STATE_EXEC, 5'b010_xx}: + state <= `STATE_WRITEBACK; + {1'b0, `STATE_WRITEBACK, 5'b010_xx}: + state <= `STATE_IF; + + /* Should not happen. Otherwise, an error occurred. */ + default: + state <= `STATE_RESET; + endcase +endmodule: statemachine diff --git a/testbenches/cpu_tb.sv b/testbenches/cpu_tb.sv new file mode 100644 index 0000000..6f936b1 --- /dev/null +++ b/testbenches/cpu_tb.sv @@ -0,0 +1,41 @@ +`define M_NOP 2'b00 +`define M_READ 2'b10 +`define M_WRITE 2'b01 + +module cpu_tb; + reg err, clk, reset; + + tb_top DUT(clk, reset); + + initial forever begin + clk = 0; #5; + clk = 1; #5; + end + + initial begin + #2000; + $display("Time limit reached.\n"); + $stop; + end + + initial begin + reset = 1'b1; + #10; + reset = 1'b0; + end +endmodule: cpu_tb + +module tb_top(input clk, input reset); + wire write, N, V, Z; + wire [1:0] mem_cmd; + wire [8:0] mem_addr; + wire [15:0] din, dout, mem_data; + + ram #(16, 8, "data_cpu_tb.txt") MEM(clk, mem_addr[7:0], write, din, dout); + cpu CPU(clk, reset, mem_data, mem_cmd, mem_addr, din, N, V, Z); + + assign mem_data = (mem_cmd == `M_READ & ~mem_addr[8]) + ? dout : {16{1'bz}}; + assign din = {16{1'bz}}; + assign write = mem_cmd == `M_WRITE & ~mem_addr[8]; +endmodule: tb_top diff --git a/testbenches/lab7_autograder_check.sv b/testbenches/lab7_autograder_check.sv new file mode 100644 index 0000000..f72627c --- /dev/null +++ b/testbenches/lab7_autograder_check.sv @@ -0,0 +1,66 @@ +module lab7_check_tb; + reg err; + reg [3:0] KEY; + reg [9:0] SW; + wire [6:0] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5; + wire [9:0] LEDR; + + lab7_top DUT(KEY, SW, LEDR, HEX0, HEX1, HEX2, HEX3, HEX4, HEX5); + + initial forever begin + KEY[0] = 0; #5; + KEY[0] = 1; #5; + end + + initial begin + #500; + $display("Time limit reached.\n"); + $stop; + end + + initial begin + err = 0; + KEY[1] = 1'b0; + + if (DUT.MEM.mem[0] !== 16'b1101000000000101) begin err = 1; $display("FAILED: mem[0] wrong; please set data.txt using Figure 6"); $stop; end + if (DUT.MEM.mem[1] !== 16'b0110000000100000) begin err = 1; $display("FAILED: mem[1] wrong; please set data.txt using Figure 6"); $stop; end + if (DUT.MEM.mem[2] !== 16'b1101001000000110) begin err = 1; $display("FAILED: mem[2] wrong; please set data.txt using Figure 6"); $stop; end + if (DUT.MEM.mem[3] !== 16'b1000001000100000) begin err = 1; $display("FAILED: mem[3] wrong; please set data.txt using Figure 6"); $stop; end + if (DUT.MEM.mem[4] !== 16'b1110000000000000) begin err = 1; $display("FAILED: mem[4] wrong; please set data.txt using Figure 6"); $stop; end + if (DUT.MEM.mem[5] !== 16'b1010101111001101) begin err = 1; $display("FAILED: mem[5] wrong; please set data.txt using Figure 6"); $stop; end + + @(negedge KEY[0]); + + KEY[1] = 1'b1; + + #10; + + if (DUT.CPU.PC !== 9'b0) begin err = 1; $display("FAILED: PC is not reset to zero."); $stop; end + + @(posedge DUT.CPU.PC or negedge DUT.CPU.PC); + + if (DUT.CPU.PC !== 9'h1) begin err = 1; $display("FAILED: PC should be 1."); $stop; end + + @(posedge DUT.CPU.PC or negedge DUT.CPU.PC); + + if (DUT.CPU.PC !== 9'h2) begin err = 1; $display("FAILED: PC should be 2."); $stop; end + if (DUT.CPU.DP.REGFILE.R0 !== 16'h5) begin err = 1; $display("FAILED: R0 should be 5."); $stop; end + + @(posedge DUT.CPU.PC or negedge DUT.CPU.PC); + + if (DUT.CPU.PC !== 9'h3) begin err = 1; $display("FAILED: PC should be 3."); $stop; end + if (DUT.CPU.DP.REGFILE.R1 !== 16'hABCD) begin err = 1; $display("FAILED: R1 should be 0xABCD. Looks like your LDR isn't working."); $stop; end + + @(posedge DUT.CPU.PC or negedge DUT.CPU.PC); + + if (DUT.CPU.PC !== 9'h4) begin err = 1; $display("FAILED: PC should be 4."); $stop; end + if (DUT.CPU.DP.REGFILE.R2 !== 16'h6) begin err = 1; $display("FAILED: R2 should be 6."); $stop; end + + @(posedge DUT.CPU.PC or negedge DUT.CPU.PC); + + if (DUT.CPU.PC !== 9'h5) begin err = 1; $display("FAILED: PC should be 5."); $stop; end + if (DUT.MEM.mem[6] !== 16'hABCD) begin err = 1; $display("FAILED: mem[6] wrong; looks like your STR isn't working"); $stop; end + + if (~err) $display("INTERFACE OK"); + end +endmodule: lab7_check_tb diff --git a/testbenches/lab7bonus_autograder_check.sv b/testbenches/lab7bonus_autograder_check.sv new file mode 100644 index 0000000..b68ae32 --- /dev/null +++ b/testbenches/lab7bonus_autograder_check.sv @@ -0,0 +1,76 @@ +module lab7bonus_check_tb; + reg [3:0] KEY; + reg [9:0] SW; + wire [9:0] LEDR; + wire [6:0] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5; + reg err; + reg CLOCK_50; + + lab7bonus_top DUT(KEY,SW,LEDR,HEX0,HEX1,HEX2,HEX3,HEX4,HEX5,CLOCK_50); + + initial forever begin + CLOCK_50 = 0; #5; + CLOCK_50 = 1; #5; + end + + initial begin + #2000; + $stop; + end + + initial begin + err = 0; + KEY[1] = 1'b0; // reset asserted + // check if program from Figure 2 in Lab 8 handout can be found loaded in memory + if (DUT.MEM.mem[0] !== 16'b1101000000001111) begin err = 1; $display("FAILED: mem[0] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end + if (DUT.MEM.mem[1] !== 16'b0110000000000000) begin err = 1; $display("FAILED: mem[1] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end + if (DUT.MEM.mem[2] !== 16'b1101000100000000) begin err = 1; $display("FAILED: mem[2] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end + if (DUT.MEM.mem[3] !== 16'b1101001000000000) begin err = 1; $display("FAILED: mem[3] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end + if (DUT.MEM.mem[4] !== 16'b1101001100010000) begin err = 1; $display("FAILED: mem[4] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end + if (DUT.MEM.mem[5] !== 16'b1101010000000001) begin err = 1; $display("FAILED: mem[5] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end + if (DUT.MEM.mem[6] !== 16'b1010001110100001) begin err = 1; $display("FAILED: mem[6] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end + if (DUT.MEM.mem[7] !== 16'b0110010110100000) begin err = 1; $display("FAILED: mem[7] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end + if (DUT.MEM.mem[8] !== 16'b1010001001000101) begin err = 1; $display("FAILED: mem[8] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end + if (DUT.MEM.mem[9] !== 16'b1010000100100100) begin err = 1; $display("FAILED: mem[9] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end + if (DUT.MEM.mem[10] !== 16'b1010100100000000) begin err = 1; $display("FAILED: mem[10] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end + if (DUT.MEM.mem[11] !== 16'b0010001111111010) begin err = 1; $display("FAILED: mem[11] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end + if (DUT.MEM.mem[12] !== 16'b1101001100010100) begin err = 1; $display("FAILED: mem[12] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end + if (DUT.MEM.mem[13] !== 16'b1000001101000000) begin err = 1; $display("FAILED: mem[13] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end + if (DUT.MEM.mem[14] !== 16'b1110000000000000) begin err = 1; $display("FAILED: mem[14] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end + if (DUT.MEM.mem[15] !== 16'b0000000000000100) begin err = 1; $display("FAILED: mem[15] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end + if (DUT.MEM.mem[16] !== 16'b0000000000110010) begin err = 1; $display("FAILED: mem[16] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end + if (DUT.MEM.mem[17] !== 16'b0000000011001000) begin err = 1; $display("FAILED: mem[17] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end + if (DUT.MEM.mem[18] !== 16'b0000000001100100) begin err = 1; $display("FAILED: mem[18] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end + if (DUT.MEM.mem[19] !== 16'b0000000111110100) begin err = 1; $display("FAILED: mem[19] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end + if (DUT.MEM.mem[20] !== 16'b1011101011011101) begin err = 1; $display("FAILED: mem[20] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end + if (DUT.MEM.mem[21] !== 16'b0000000000000000) begin err = 1; $display("FAILED: mem[21] wrong; please set data.txt using lab7bonusfig2.s"); $stop; end + + #10; // wait until next falling edge of clock + KEY[1] = 1'b1; // reset de-asserted, PC still undefined if as in Figure 4 + + #10; // waiting for RST state to cause reset of PC + if (DUT.CPU.PC !== 9'h0) begin err = 1; $display("FAILED: PC did not reset to 0."); $stop; end + + // If your simlation never gets past the the line below, check if your CMP instruction is working + @(posedge LEDR[8]); // set LEDR[8] to one when executing HALT + + // NOTE: your program counter register output should be called PC and be inside a module with instance name CPU + // NOTE: if HALT is working, PC won't change after reaching 0xE + if (DUT.CPU.PC !== 9'hF) begin err = 1; $display("FAILED: PC at HALT is incorrect."); $stop; end + if (DUT.CPU.DP.REGFILE.R4 !== 16'h1) begin err = 1; $display("FAILED: R4 incorrect at exit; did MOV R4,#1 not work?"); $stop; end + if (DUT.CPU.DP.REGFILE.R0 !== 16'h4) begin err = 1; $display("FAILED: R0 incorrect at exit; did LDR R0,[R0] not work?"); $stop; end + + // check memory contents for result + if (DUT.MEM.mem[8'h14] === 16'h0) begin + err = 1; + $display("FAILED: mem[0x14] (result) is wrong;"); + if (DUT.CPU.DP.REGFILE.R3 === 16'h10) + $display(" hint: check if your BLT instruction skipped MOV R3, result"); + $stop; + end + if (DUT.MEM.mem[8'h14] !== 16'd850) begin err = 1; $display("FAILED: mem[0x14] (result) is wrong;"); $stop; end + + if (~err) $display("INTERFACE OK"); + $stop; + end +endmodule diff --git a/testbenches/lab7bonus_stage2_tb.sv b/testbenches/lab7bonus_stage2_tb.sv new file mode 100644 index 0000000..d5708eb --- /dev/null +++ b/testbenches/lab7bonus_stage2_tb.sv @@ -0,0 +1,49 @@ +`define STATE_RESET 3'b000 +`define STATE_HALT 3'b001 +`define STATE_IF 3'b010 +`define STATE_DECODE 3'b011 +`define STATE_EXEC 3'b100 +`define STATE_MEM 3'b101 +`define STATE_WRITEBACK 3'b110 + +module lab7bonus_stage2_tb; + reg [3:0] KEY; + reg [9:0] SW; + wire [9:0] LEDR; + wire [6:0] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5; + reg err; + reg CLOCK_50; + + lab7bonus_top DUT(KEY,SW,LEDR,HEX0,HEX1,HEX2,HEX3,HEX4,HEX5,CLOCK_50); + + initial forever begin + CLOCK_50 = 0; #5; + CLOCK_50 = 1; #5; + end + + initial begin + #2000; + $stop; + end + + wire break = (LEDR[8] == 1'b1); + initial begin + err = 0; + KEY[1] = 1'b0; // reset asserted + #10; // wait until next falling edge of clock + KEY[1] = 1'b1; // reset de-asserted, PC still undefined if as in Figure 4 + while (~break) begin + // Change the following line to wait until your CPU starts to you fetch + // the next instruction (e.g., IF1 state from Lab 7 or equivalent in + // your design). DUT.CPU.FSM is not required for by the autograder + // for Lab 8. + @(posedge (DUT.CPU.FSM.state == `STATE_IF) or posedge break); + + @(negedge CLOCK_50); // show advance to negative edge of clock + $display("PC = %h", DUT.CPU.PC); + end + if (DUT.MEM.mem[25] !== -16'd23) begin err = 1; $display("FAILED: mem[25] wrong"); $stop; end + if (~err) $display("PASSED"); + $stop; + end +endmodule diff --git a/testbenches/wave.do b/testbenches/wave.do new file mode 100644 index 0000000..b5af4f9 --- /dev/null +++ b/testbenches/wave.do @@ -0,0 +1,66 @@ +radix define states { + "3'b000" "RESET", + "3'b001" "HALT", + "3'b010" "FETCH", + "3'b011" "DECODE", + "3'b100" "EXECUTE", + "3'b101" "MEMORY", + "3'b110" "WRITEBACK", + -default default +} +radix define memory { + "2'b00" "NOP", + "2'b01" "WRITE", + "2'b10" "READ", + -default default +} + +add wave -noupdate /lab7bonus_tb/err +add wave -noupdate /lab7bonus_tb/DUT/CPU/clk +add wave -noupdate /lab7bonus_tb/DUT/CPU/reset +add wave -noupdate /lab7bonus_tb/DUT/CPU/instruction +add wave -noupdate -radix hexadecimal /lab7bonus_tb/DUT/CPU/PC +add wave -noupdate -radix hexadecimal /lab7bonus_tb/DUT/CPU/pc_next +add wave -noupdate -radix states /lab7bonus_tb/DUT/CPU/FSM/state +add wave -noupdate -expand -group {Instruction decoder} /lab7bonus_tb/DUT/CPU/opcode +add wave -noupdate -expand -group {Instruction decoder} /lab7bonus_tb/DUT/CPU/op +add wave -noupdate -expand -group {Instruction decoder} /lab7bonus_tb/DUT/CPU/sh +add wave -noupdate -expand -group {Instruction decoder} /lab7bonus_tb/DUT/CPU/Rn +add wave -noupdate -expand -group {Instruction decoder} /lab7bonus_tb/DUT/CPU/Rd +add wave -noupdate -expand -group {Instruction decoder} /lab7bonus_tb/DUT/CPU/Rm +add wave -noupdate -expand -group {Instruction decoder} -radix hexadecimal /lab7bonus_tb/DUT/CPU/sximm5 +add wave -noupdate -expand -group {Instruction decoder} -radix hexadecimal /lab7bonus_tb/DUT/CPU/sximm8 +add wave -noupdate -divider {PIPELINE REGISTERS} +add wave -noupdate -radix hexadecimal /lab7bonus_tb/DUT/CPU/DP/aout +add wave -noupdate -radix hexadecimal /lab7bonus_tb/DUT/CPU/DP/bout +add wave -noupdate -divider {CONTROL SIGNALS} +add wave -noupdate -expand -group {CPU Signals} /lab7bonus_tb/DUT/CPU/pc_reset +add wave -noupdate -expand -group {CPU Signals} /lab7bonus_tb/DUT/CPU/pc_load +add wave -noupdate -expand -group {CPU Signals} /lab7bonus_tb/DUT/CPU/ir_load +add wave -noupdate -expand -group {CPU Signals} /lab7bonus_tb/DUT/CPU/addr_sel +add wave -noupdate -expand -group {CPU Signals} -radix memory /lab7bonus_tb/DUT/CPU/mem_cmd +add wave -noupdate -expand -group {Datapath Signals} /lab7bonus_tb/DUT/CPU/write +add wave -noupdate -expand -group {Datapath Signals} /lab7bonus_tb/DUT/CPU/loada +add wave -noupdate -expand -group {Datapath Signals} /lab7bonus_tb/DUT/CPU/loadb +add wave -noupdate -expand -group {Datapath Signals} /lab7bonus_tb/DUT/CPU/loadc +add wave -noupdate -expand -group {Datapath Signals} /lab7bonus_tb/DUT/CPU/loads +add wave -noupdate -expand -group {Datapath Signals} /lab7bonus_tb/DUT/CPU/loadm +add wave -noupdate -expand -group {Datapath Signals} /lab7bonus_tb/DUT/CPU/asel +add wave -noupdate -expand -group {Datapath Signals} /lab7bonus_tb/DUT/CPU/bsel +add wave -noupdate -expand -group {Datapath Signals} /lab7bonus_tb/DUT/CPU/csel +add wave -noupdate -divider OUTPUT +add wave -noupdate -radix hexadecimal /lab7bonus_tb/DUT/CPU/mem_addr +add wave -noupdate /lab7bonus_tb/DUT/CPU/out +add wave -noupdate -expand -group Status /lab7bonus_tb/DUT/CPU/DP/N +add wave -noupdate -expand -group Status /lab7bonus_tb/DUT/CPU/DP/V +add wave -noupdate -expand -group Status /lab7bonus_tb/DUT/CPU/DP/Z +add wave -noupdate -divider REGISTERS/MEMORY +add wave -noupdate -expand -group Registers -radix hexadecimal /lab7bonus_tb/DUT/CPU/DP/REGFILE/R0 +add wave -noupdate -expand -group Registers -radix hexadecimal /lab7bonus_tb/DUT/CPU/DP/REGFILE/R1 +add wave -noupdate -expand -group Registers -radix hexadecimal /lab7bonus_tb/DUT/CPU/DP/REGFILE/R2 +add wave -noupdate -expand -group Registers -radix hexadecimal /lab7bonus_tb/DUT/CPU/DP/REGFILE/R3 +add wave -noupdate -expand -group Registers -radix hexadecimal /lab7bonus_tb/DUT/CPU/DP/REGFILE/R4 +add wave -noupdate -expand -group Registers -radix hexadecimal /lab7bonus_tb/DUT/CPU/DP/REGFILE/R5 +add wave -noupdate -expand -group Registers -radix hexadecimal /lab7bonus_tb/DUT/CPU/DP/REGFILE/R6 +add wave -noupdate -expand -group Registers -radix hexadecimal /lab7bonus_tb/DUT/CPU/DP/REGFILE/R7 +add wave -noupdate -radix decimal /lab7bonus_tb/DUT/MEM/mem diff --git a/trigger.py b/trigger.py deleted file mode 100644 index 72ecf10..0000000 --- a/trigger.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/python3 -# WARNING: Do not modify this file unless directed to do so by your instructor - -import requests -import os -import re - -def notify_autograder(lab,section,student): - API_ENDPOINT = "https://cpen211.ece.ubc.ca/autograder_build_request.php" - data = {'github_username':student, - 'lab':lab, - 'section':section} - r = requests.post(url=API_ENDPOINT, data=data, timeout=5) - if r.text == 'OK': - print('Queuing your submission for ranking. You will be emailed when results are available.') - else: - print('ERROR unable to queue your submission for ranking; notify instructor.') - print('Response from server -->') - print(r.text); - print('<---') - -m = re.search(r'lab-7-l1[a-z]-bonus-([^/])+/lab-7-l1(?P<section>[a-z])-bonus-(?P<user>\S+)', os.getcwd()) -if m: - github_username = m.group('user') - print("Username: " + github_username) - section = m.group('section').upper() - print("Section: L1" + section) -else: - print("ERROR: Did not match regex. Unable to queue your submission for ranking; notify instructor.") - exit(1) -notify_autograder(8,section,github_username) |