Compare commits

...
4 Commits
10 changed files with 410 additions and 9 deletions

No files matched your search

@@ -0,0 +1,18 @@
01084023
25090007
ad090000
8d0a0000
012a5821
012b6022
212d0003
018d7020
012d8024
012d8825
012d9026
012d9827
018ea02a
018ea82b
25080001
010db02b
12d4fffd
12d6ffff
@@ -0,0 +1,51 @@
// $File: NewcastleUniversity/ELEC4720/2026s2/src/Code/Assignment/Ass-03-HazardsDemo.txt $
// $Date: 2026-10-29 14:44:32 +1100 (Thu, 29 Oct 2026) $
// $Revision: 2531 $
// $Author: Peter $
//
// Course: ELEC4720(2026s2) Programmable Logic Design
// School: Engineering
// University: The University of Newcastle
// Address: CALLAGHAN NSW 2308 Australia
//
// Author: Dr Peter Stepien
// Email: peter.stepien@newcastle.edu.au
// Copyright: 2026
// Assignment 3 Demonstration Program (with hazards)
// main:
// Initialise some registers
01084023 // subu $t0, $t0, $t0
25090007 // addiu $t1, $t0, 7
// Memory operations
ad090000 // sw $t1, 0x0000($t0)
8d0a0000 // lw $t2, 0x0000($t0)
// Remaining arithmetic
012a5821 // addu $t3, $t1, $t2
012b6022 // sub $t4, $t1, $t3
212d0003 // addi $t5, $t1, 3
018d7020 // add $t6, $t4, $t5
// Logical
012d8024 // and $s0, $t1, $t5
012d8825 // or $s1, $t1, $t5
012d9026 // xor $s2, $t1, $t5
012d9827 // nor $s3, $t1, $t5
// Comparison
018ea02a // slt $s4, $t4, $t6
018ea82b // sltu $s5, $t4, $t6
// Loop to test branch
// loop:
25080001 // addiu $t0, $t0, 1
010db02b // sltu $s6, $t0, $t5
12d4fffd // beq $s6, $s4, loop
// Endless loop at end of program (FPGA)
// finish:
12d6ffff // beq $s6, $s6, finish
@@ -0,0 +1,34 @@
01084023
01294823
014a5023
016b5823
25090007
ad090000
014a5023
016b5823
018c6023
8d0a0000
016b5823
018c6023
01ad6823
012a5821
018c6023
01ad6823
01ce7023
012b6022
212d0003
01ce7023
01ef7823
02108023
018d7020
012d8024
012d8825
012d9026
012d9827
018ea02a
018ea82b
1211ffff
1211fffe
1211fffd
1211fffc
12d6ffff
@@ -0,0 +1,50 @@
// $File: NewcastleUniversity/ELEC4720/2026s2/src/Code/Assignment/Ass-03-NoHazardsDemo.txt $
// $Date: 2026-10-29 14:44:32 +1100 (Thu, 29 Oct 2026) $
// $Revision: 2531 $
// $Author: Peter $
//
// Course: ELEC4720(2026s2) Programmable Logic Design
// School: Engineering
// University: The University of Newcastle
// Address: CALLAGHAN NSW 2308 Australia
//
// Author: Dr Peter Stepien
// Email: peter.stepien@newcastle.edu.au
// Copyright: 2026
// Assignment 3 Demonstration Program (without hazards)
01084023
01294823
014a5023
016b5823
25090007
ad090000
014a5023
016b5823
018c6023
8d0a0000
016b5823
018c6023
01ad6823
012a5821
018c6023
01ad6823
01ce7023
012b6022
212d0003
01ce7023
01ef7823
02108023
018d7020
012d8024
012d8825
012d9026
012d9827
018ea02a
018ea82b
1211ffff
1211fffe
1211fffd
1211fffc
12d6ffff
@@ -0,0 +1,61 @@
# $File: NewcastleUniversity/ELEC4720/2026s2/src/Code/Assignment/Ass-02-Demo.s $
# $Date: 2026-10-07 01:54:03 +1100 (Wed, 07 Oct 2026) $
# $Revision: 2525 $
# $Author: Peter $
#
# Course: ELEC4720(2026s2) Programmable Logic Design
# School: Engineering
# University: The University of Newcastle
# Address: CALLAGHAN NSW 2308 Australia
#
# Author: Dr Peter Stepien
# Email: peter.stepien@newcastle.edu.au
# Copyright: 2026
# Assignment 3 Demonstration Program (with hazards)
.text
.globl main
.globl loop
.globl finish
main:
# Initialise some registers
subu $t0, $t0, $t0 # Set t0 = 0 (R8, modified below)
addiu $t1, $t0, 7 # Set t1 = 7 (R9)
# Memory operations
sw $t1, 0x10000000($t0) # Save t1 to memory (change to 0x0000 for FPGA)
lw $t2, 0x10000000($t0) # Load t2 from memory (change to 0x0000 for FPGA) (R10)
# Remaining arithmetic
addu $t3, $t1, $t2 # Unsigned t3 = t1 + t2 = 14 (R11)
sub $t4, $t1, $t3 # Signed t4 = t1 - t3 = -7 (R12)
addi $t5, $t1, 3 # Signed t5 = t1 + 3 = 10 (R13)
add $t6, $t4, $t5 # Signed t6 = t4 + t5 = 3 (R14)
# Logical (t1 = 0000..0111, t5 = 0000..1010)
and $s0, $t1, $t5 # s0 = t1 and t5 = 2 (0000..0010) (R16)
or $s1, $t1, $t5 # s1 = t1 or t5 = 15 (0000..1111) (R17)
xor $s2, $t1, $t5 # s2 = t1 xor t5 = 13 (0000..1101) (R18)
nor $s3, $t1, $t5 # s3 = t1 nor t5 = -16 (1111..0000) (R19)
# Comparison
slt $s4, $t4, $t6 # Signed s4 = t4 < t6 = 1 (true) (R20)
sltu $s5, $t4, $t6 # Unsigned s5 = t4 < t6 = 0 (false) (R21)
# Loop to test branch
loop:
addiu $t0, $t0, 1 # Increment counter
sltu $s6, $t0, $t5 # Unsigned s6 = t0 < t5 (Last 0) (R22)
beq $s6, $s4, loop # Loop if s6 == s4
# Endless loop at end of program (FPGA)
finish:
# beq $s6, $s6, finish # Endless loop
# Alternative system call to exit program (spim)
li $v0, 10
syscall
# END OF FILE
@@ -0,0 +1,77 @@
# $File: NewcastleUniversity/ELEC4720/2026s2/src/Code/Assignment/Ass-02-Demo.s $
# $Date: 2026-10-07 01:54:03 +1100 (Wed, 07 Oct 2026) $
# $Revision: 2525 $
# $Author: Peter $
#
# Course: ELEC4720(2026s2) Programmable Logic Design
# School: Engineering
# University: The University of Newcastle
# Address: CALLAGHAN NSW 2308 Australia
#
# Author: Dr Peter Stepien
# Email: peter.stepien@newcastle.edu.au
# Copyright: 2026
# Assignment 3 Demonstration Program (without hazards)
.text
.globl main
.globl loop
.globl finish
main:
# Set registers to zero
subu $t0, $t0, $t0 # Set t0 = 0 (R8)
subu $t1, $t1, $t1 # Set t1 = 0
subu $t2, $t2, $t2 # Set t2 = 0
subu $t3, $t3, $t3 # Set t3 = 0
addiu $t1, $t0, 7 # Set t1 = 7 (R9)
# Memory operations
sw $t1, 0x10000000($t0) # Save t1 to memory (change to 0x0000 for FPGA)
subu $t2, $t2, $t2 # Set t2 = 0
subu $t3, $t3, $t3 # Set t3 = 0
subu $t4, $t4, $t4 # Set t4 = 0
lw $t2, 0x10000000($t0) # Load t2 from memory (change to 0x0000 for FPGA) (R10)
subu $t3, $t3, $t3 # Set t3 = 0
subu $t4, $t4, $t4 # Set t4 = 0
subu $t5, $t5, $t5 # Set t5 = 0
# Remaining arithmetic
addu $t3, $t1, $t2 # Unsigned t3 = t1 + t2 = 14 (R11)
subu $t4, $t4, $t4 # Set t4 = 0
subu $t5, $t5, $t5 # Set t5 = 0
subu $t6, $t6, $t6 # Set t6 = 0
sub $t4, $t1, $t3 # Signed t4 = t1 - t3 = -7 (R12)
addi $t5, $t1, 3 # Signed t5 = t1 + 3 = 10 (R13)
subu $t6, $t6, $t6 # Set t6 = 0
subu $t7, $t7, $t7 # Set t7 = 0
subu $s0, $s0, $s0 # Set s0 = 0
add $t6, $t4, $t5 # Signed t6 = t4 + t5 = 3 (R14)
# Logical (t1 = 0000..0111, t5 = 0000..1010)
and $s0, $t1, $t5 # s0 = t1 and t5 = 2 (0000..0010) (R16)
or $s1, $t1, $t5 # s1 = t1 or t5 = 15 (0000..1111) (R17)
xor $s2, $t1, $t5 # s2 = t1 xor t5 = 13 (0000..1101) (R18)
nor $s3, $t1, $t5 # s3 = t1 nor t5 = -16 (1111..0000) (R19)
# Comparison
slt $s4, $t4, $t6 # Signed s4 = t4 < t6 = 1 (true) (R20)
sltu $s5, $t4, $t6 # Unsigned s5 = t4 < t6 = 0 (false) (R21)
# Never branches (need to manually stop program for Q1)
loop:
beq $s0, $s1, loop # Loop if s0 == s1
beq $s0, $s1, loop # Loop if s0 == s1
beq $s0, $s1, loop # Loop if s0 == s1
beq $s0, $s1, loop # Loop if s0 == s1
# Endless loop at end of program (FPGA)
finish:
# beq $s6, $s6, finish # Endless loop
# Alternative system call to exit program (spim)
li $v0, 10
syscall
# END OF FILE
+107
View File
@@ -0,0 +1,107 @@
`ifndef ASS_3_SV
`define ASS_3_SV
`include "rom.sv"
`include "ram.sv"
`include "register_file.sv"
`include "instruction_counter.sv"
`include "control_unit.sv"
`include "alu.sv"
`include "shifter.sv"
`include "sign_extender.sv"
`include "gatereg.sv"
`ifdef QUARTUS_SYNTH
`include "seven_seg_4digit.sv"
`endif
module assignment3 #(width, romsz, ramsz)(
input logic [0:0] clk, input logic [0:0] rst,
`ifdef QUARTUS_SYNTH
,
input logic [4:0] HID_Register,
input logic [0:0] HID_PC,
input logic [0:0] HID_Hi_Low,
output logic[7:0] out_seg_0,
output logic[7:0] out_seg_1,
output logic[7:0] out_seg_2,
output logic[7:0] out_seg_3
`endif
);
logic [2**width-1:0] pc_addr, pc_addr_2;
logic [2**width-1:0] pc_addr_write;
logic [0:0] pc_we;
// TODO: Verify if we need a clk gating on pc_addr
instruction_counter #(width) PC (clk, rst, pc_we, pc_addr_write, pc_addr);
gatereg #(width, 2) gate_pc_addr(clk, rst, 1, pc_addr, pc_addr_2);
logic [2**width-1:0] rom_rd;
logic [2**width-1:0] rom_addr;
logic [2**width-1:0] instruction, instruction_1;
rom #(romsz, width) ROM (rom_addr, rom_rd);
gatereg #(width, 1) gate_pc_addr(clk, rst, 1, pc_addr, rom_addr);
gatereg #(width, 1) gate_instruction(clk, rst, 1, rom_rd, instruction);
gatereg #(width, 1) gate_instruction_1(clk, rst, 1, instruction, instruction_1);
logic [0:0] cu_m2r, cu_m2w, cu_b, cu_alu_src, cu_rdst, cu_rw;
logic [3:0] cu_alu_fn, ALU_FN;
logic [0:0] B, MEM_WE, RDST, ALU_SRC, REG_WE, REGW_MEM_OR_RD;
control_unit CONTROL_UNIT (instruction[31:26], instruction[5:0],
cu_m2r, cu_m2w, cu_b, cu_alu_fn, cu_alu_src, cu_rdst, cu_rw
);
gatereg #(0, 1) gate_cu_rdst (clk, rst, 1, cu_rdst, RDST);
gatereg #(0, 1) gate_cu_alu_src (clk, rst, 1, cu_alu_src, ALU_SRC);
gatereg #(2, 1) gate_cu_alu_fn (clk, rst, 1, cu_alu_fn, ALU_FN);
gatereg #(0, 2) gate_cu_b (clk, rst, 1, cu_b, B);
gatereg #(0, 2) gate_cu_m2w (clk, rst, 1, cu_m2w, MEM_WE);
gatereg #(0, 3) gate_cu_rw (clk, rst, 1, cu_rw, REG_WE);
gatereg #(0, 3) gate_cu_m2r (clk, rst, 1, cu_m2r, REGW_MEM_OR_RD);
logic [2**width-1:0] regf_rs, regf_rs_1;
logic [2**width-1:0] regf_rt, regf_rt_1, regf_rt_2;
logic [7:0] regf_a3, regf_a3_2;
assign rd = (REGW_MEM_OR_RD) ? rd_mem : alu_out_2;
assign regf_a3 = (RDST) ? instruction_1[15:11] : instruction_1[20:16];
// TODO: Connect inputs
gatereg #(3, 2) gate_regf_a3 (clk, rst, 1, regf_a3, regf_a3_2);
register_file #(width, 5) REGS (
~clk, REG_WE,
regf_a3_2 & 8'b00011111, rd,
instruction[25:21], regf_rs,
instruction[20:16], regf_rt,
regs_out
);
gatereg #(width, 1) gate_regf_rs(clk, rst, 1, regf_rs, regf_rs_1);
gatereg #(width, 1) gate_regf_rt(clk, rst, 1, regf_rt, regf_rt_1);
gatereg #(width, 1) gate_regf_rt_1(clk, rst, 1, regf_rt_1, regf_rt_2);
logic [2**width-1:0] sign_ext_imm, rt_imm;
sign_extender #(4, width) SIGNEXT(1'b1, instruction[15:0], sign_ext_imm);
gatereg #(width, 1) gate_sign_ext_imm(clk, rst, 1, sign_ext_imm, rt_imm);
logic [2**width-1:0] alu_out, alu_out_1, alu_out_2;
logic [3:0] alu_flags, alu_flags_1;
alu #(width) ALU (ALU_FN, regf_rs_1, (ALU_SRC) ? rt_imm : regf_rt_1, rd_alu, alu_flags);
gatereg #(width, 1) gate_alu_out (clk, rst, 1, alu_out, alu_out_1);
gatereg #(width, 1) gate_alu_out_1 (clk, rst, 1, alu_out_1, alu_out_2);
gatereg #(width, 1) gate_alu_flags (clk, rst, 1, alu_flags, alu_flags_1);
logic [2**width-1:0] new_pc_addr, new_pc_addr_1;
assign new_pc_addr = (rt_imm << 2) + pc_addr_2;
gatereg #(width, 1) gate_new_pc_addr (clk, rst, 1, new_pc_addr, new_pc_addr_1);
assign pc_addr_write = new_pc_addr_1;
assign pc_we = B & alu_flags_1[2];
logic [2**width-1:0] mem_out, mem_out_1;
ram #(ramsz, width) RAM (clk, rst, alu_out_1, MEM_WE, regf_rt_2, mem_out);
gatereg #(width, 1) gate_mem_out (clk, rst, 1, mem_out, mem_out_1);
assign rd_mem = mem_out_1;
endmodule
`endif
+7 -4
View File
@@ -1,15 +1,18 @@
module gatereg #(width)(
module gatereg #(width, ndelay=1)(
input logic [0:0] clk, input logic [0:0] rst, input logic en[0:0],
input logic [2**width-1:0] in, output logic [2**width-1:0] out
);
logic [2**width-1:0] hold_value;
logic [2**width-1:0] hold_value[ndelay];
assign out = hold_value;
assign out = hold_value[ndelay-1];
always_ff @( posedge clk ) begin
if (rst) begin
hold_value <= {(2**width){0}};
end else if (en) begin
hold_value <= in;
hold_value[0] <= in;
for (int i = 1; i < ndelay; ++i) begin
hold_value[i] <= hold_value[i-1];
end
end
end
+4 -4
View File
@@ -13,7 +13,7 @@
num_errors += 1; \
end
module mips_tb();
module mips_single_cycle_tb();
logic [0:0] clk;
logic [0:0] rst;
assignment2 #(5) CPU (clk, rst);
@@ -42,7 +42,7 @@ module mips_tb();
$dumpvars(7, CPU.rt_imm);
// Zero out lower registers
$display("Beginning MIPS tests");
$display("Beginning Single-cycle MIPS tests");
// Check R-type / initialise
#2;
@@ -119,8 +119,8 @@ module mips_tb();
`TEST_CHECK(CPU.REGS.regs[22] == 32'd0);
`TEST_CHECK(CPU.REGS.regs[23] == 32'd0);
if (num_errors == 0) begin $display("\x1b[38;5;10mAll MIPS tests passing\x1b[m");
end else begin $display("\x1b[38;5;9m%0d MIPS test(s) failing\x1b[m", num_errors); end
if (num_errors == 0) begin $display("\x1b[38;5;10mAll Single-cycle MIPS tests passing\x1b[m");
end else begin $display("\x1b[38;5;9m%0d Single-cycle MIPS test(s) failing\x1b[m", num_errors); end
$dumpflush;
$finish;
+1 -1
View File
@@ -4,4 +4,4 @@
`include "tests/instruction_classifier_tb.sv"
`include "tests/shifter_tb.sv"
`include "tests/alu_tb.sv"
`include "tests/mips.sv"
`include "tests/mips_singlecycle.sv"