aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkryptoish <krish_thakur7@icloud.com>2024-12-07 22:12:43 -0800
committerkryptoish <krish_thakur7@icloud.com>2024-12-07 22:12:43 -0800
commitf9d92b31e4bea3037c75f7c7a508c1be09811fd0 (patch)
tree5cd7160603f0841c0661e5c50fca5e3c28b96af4
parentadded files (diff)
Final Working Version
-rw-r--r--.editorconfig9
-rw-r--r--README.md42
-rw-r--r--alu.sv21
-rw-r--r--cpu.sv150
-rw-r--r--data.txt256
-rw-r--r--datapath.sv48
-rw-r--r--images/rankings.pngbin0 -> 146114 bytes
-rw-r--r--lab7bonus_autograder_check.sv71
-rw-r--r--lab7bonus_fig2.s28
-rw-r--r--lab7bonus_fig4.s29
-rw-r--r--lab7bonus_stage2_tb.sv35
-rw-r--r--lab7bonus_top.sv90
-rw-r--r--mem/data.txt256
-rw-r--r--mem/data_cpu_tb.txt256
-rw-r--r--mem/data_lab8_check.txt256
-rw-r--r--mem/data_lab8_stage2.txt256
-rw-r--r--regfile.sv45
-rw-r--r--shifter.sv18
-rw-r--r--src/alu.sv17
-rw-r--r--src/cpu.sv94
-rw-r--r--src/datapath.sv38
-rw-r--r--src/lab7bonus_top.sv79
-rw-r--r--src/regfile.sv54
-rw-r--r--src/shifter.sv12
-rw-r--r--src/statemachine.sv246
-rw-r--r--testbenches/cpu_tb.sv41
-rw-r--r--testbenches/lab7_autograder_check.sv66
-rw-r--r--testbenches/lab7bonus_autograder_check.sv76
-rw-r--r--testbenches/lab7bonus_stage2_tb.sv49
-rw-r--r--testbenches/wave.do66
-rw-r--r--trigger.py31
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
diff --git a/README.md b/README.md
index 6b6a671..d88ee16 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,34 @@
-[![Review Assignment Due Date](https://classroom.github.com/assets/deadline-readme-button-22041afd0340ce965d47ae6ef1cefeee28c7c493a6346c4f15d667ab976d596c.svg)](https://classroom.github.com/a/H84oO7Rx)
-[![Open in Visual Studio Code](https://classroom.github.com/assets/open-in-vscode-2e0aaae1b6195c2367325f4f02e2d04e9abb55f0b24a779b69b11b9e10269abc.svg)](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
+![Final Ranking and Scores](images/rankings.png)
+
+---
+
+## 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.
diff --git a/alu.sv b/alu.sv
deleted file mode 100644
index 4e17d8b..0000000
--- a/alu.sv
+++ /dev/null
@@ -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
diff --git a/cpu.sv b/cpu.sv
deleted file mode 100644
index 36c0bf2..0000000
--- a/cpu.sv
+++ /dev/null
@@ -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
new file mode 100644
index 0000000..5c59454
--- /dev/null
+++ b/images/rankings.png
Binary files differ
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)