Added files into modelsim folder
This commit is contained in:
14 files changed
+431
-8
No files matched your search
@@ -0,0 +1,14 @@
|
|||||||
|
`include "rom.sv"
|
||||||
|
|
||||||
|
module ByteIM #(parameter m=5,n=2) (
|
||||||
|
input logic [m-1:0] Ad,
|
||||||
|
output logic [(2**n)*8-1:0] Dout );
|
||||||
|
|
||||||
|
// 2**n byte wide words
|
||||||
|
// m bit wide byte address
|
||||||
|
// 2**m bytes of memory
|
||||||
|
// 2**(m-n) memory words
|
||||||
|
// 2**(n+3) bit wide words
|
||||||
|
// Reads the whole word that contains the addressed byte
|
||||||
|
ROM #(m-n,2**(n+3)) wordrom(Ad[m-1:n],Dout)
|
||||||
|
endmodule
|
||||||
+6
-3
@@ -8,11 +8,13 @@
|
|||||||
// flags[1:1] = Overflow
|
// flags[1:1] = Overflow
|
||||||
module alu #(parameter width=2)(input logic [3:0] op,
|
module alu #(parameter width=2)(input logic [3:0] op,
|
||||||
input logic [2**width-1:0] A, input logic [2**width-1:0] B,
|
input logic [2**width-1:0] A, input logic [2**width-1:0] B,
|
||||||
output logic [2**width-1:0] OUT_1, output logic[1:0] flags);
|
output logic [2**width-1:0] OUT_1, output logic[2:0] flags
|
||||||
|
);
|
||||||
|
// intermediate logic for handling asu output
|
||||||
logic [0:0] asu_op;
|
logic [0:0] asu_op;
|
||||||
logic [2**width-1:0] asu_out;
|
logic [2**width-1:0] asu_out;
|
||||||
logic [1:0] asu_flags;
|
logic [2:0] asu_flags;
|
||||||
|
|
||||||
asu #(width) adder_unit(asu_op[op[1]], A, B, asu_out, asu_flags[0], asu_flags[1]);
|
asu #(width) adder_unit(asu_op[op[1]], A, B, asu_out, asu_flags[0], asu_flags[1]);
|
||||||
|
|
||||||
logic [2**width-1:0] lu_out;
|
logic [2**width-1:0] lu_out;
|
||||||
@@ -32,6 +34,7 @@ module alu #(parameter width=2)(input logic [3:0] op,
|
|||||||
4'b1011: begin OUT_1 = ~asu_flags[0] & {{(width-1){1'b0}}, 1'b1}; flags = asu_flags; end
|
4'b1011: begin OUT_1 = ~asu_flags[0] & {{(width-1){1'b0}}, 1'b1}; flags = asu_flags; end
|
||||||
default: begin OUT_1 = {(2**width){1'b0}}; flags = asu_flags; end
|
default: begin OUT_1 = {(2**width){1'b0}}; flags = asu_flags; end
|
||||||
endcase
|
endcase
|
||||||
|
asu_flags[2] = OUT_1 == 0;
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
`endif
|
`endif
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
`ifndef ASS_2_SV
|
||||||
|
`define ASS_2_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 "seven_seg_4digit.sv"
|
||||||
|
|
||||||
|
|
||||||
|
module assignment2 #(width=5, ramsz=9, romsz=10) (
|
||||||
|
input logic [0:0] clk
|
||||||
|
`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
|
||||||
|
);
|
||||||
|
// Intermediate for displaying high / low of PC or Register
|
||||||
|
logic[15:0] PC_Reg_Display;
|
||||||
|
|
||||||
|
// Program / Instruction Counter Intermediates
|
||||||
|
logic [romsz-1:0] pc_addr;
|
||||||
|
logic [romsz-1:0] pc_addr_write;
|
||||||
|
logic [0:0] pc_we;
|
||||||
|
logic [2**width-1:0] instruction;
|
||||||
|
|
||||||
|
// Instruction Classifier Intermediates
|
||||||
|
logic [0:0] M2R;
|
||||||
|
logic [0:0] M2W;
|
||||||
|
logic [0:0] B;
|
||||||
|
logic [3:0] ALU_FN;
|
||||||
|
logic [0:0] ALU_SRC;
|
||||||
|
logic [0:0] RDST;
|
||||||
|
logic [0:0] RW;
|
||||||
|
|
||||||
|
// Register File intermediates
|
||||||
|
logic [2:0] flags;
|
||||||
|
logic [2**width-1:0] rs;
|
||||||
|
logic [2**width-1:0] rt;
|
||||||
|
logic [2**width-1:0] rd;
|
||||||
|
logic [0:0] rd_we;
|
||||||
|
logic [31:0] regs_out [32];
|
||||||
|
|
||||||
|
instruction_counter #(width) PC (clk, pc_we, pc_addr_write, pc_addr);
|
||||||
|
|
||||||
|
rom #(romsz, 2**width) ROM (pc_addr, instruction);
|
||||||
|
|
||||||
|
logic [2**width-1:0] rd_mem;
|
||||||
|
ram #(ramsz, 2**width) RAM (clk, rd_alu, M2W, rt, rd_mem);
|
||||||
|
|
||||||
|
control_unit CONTROL_UNIT (instruction[31:26], instruction[5:0],
|
||||||
|
M2R, M2W, B, ALU_FN, ALU_SRC, RDST, RW
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
register_file #(width, 5) REGS (
|
||||||
|
clk, rd_we,
|
||||||
|
instruction[20:16], rd,
|
||||||
|
(RDST) ? instruction[15:11] : instruction[20:16], rt,
|
||||||
|
instruction[25:21], rs,
|
||||||
|
regs_out
|
||||||
|
);
|
||||||
|
// Always use sign-extension
|
||||||
|
logic [2**width-1:0] rt_imm;
|
||||||
|
sign_extender #(4, width) SIGNEXT(1'b1, instruction[15:0], rt_imm);
|
||||||
|
// TODO:
|
||||||
|
// - ALU srcB
|
||||||
|
// - PCBranch (rel jump of 4-byte words)
|
||||||
|
|
||||||
|
logic [2**width-1:0] rd_alu;
|
||||||
|
logic [2**width-1:0] rt_alu;
|
||||||
|
alu #(width) ALU (ALU_FN, rs, rt_alu, rd_alu, flags[1:0]);
|
||||||
|
assign rt_alu = (ALU_SRC) ? (rt_imm) : (rt);
|
||||||
|
|
||||||
|
assign pc_we = B & flags[2];
|
||||||
|
assign pc_addr_write = (rt_imm << 2) + pc_addr;
|
||||||
|
assign rd_we = RW;
|
||||||
|
assign rd = (M2R) ? rd_alu : rd_mem;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Temporary Test output
|
||||||
|
// assign PC_Reg_Display = 16'hC342;
|
||||||
|
|
||||||
|
assign PC_Reg_Display = (HID_Hi_Low) ? regs_out[HID_Register][31:16] : regs_out[HID_Register][15:0];
|
||||||
|
|
||||||
|
seven_seg_4digit display (
|
||||||
|
.num(PC_Reg_Display),
|
||||||
|
.segments0(out_seg_0),
|
||||||
|
.segments1(out_seg_1),
|
||||||
|
.segments2(out_seg_2),
|
||||||
|
.segments3(out_seg_3)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
`endif
|
||||||
+4
-1
@@ -4,9 +4,11 @@
|
|||||||
module asu #(parameter width = 2)(
|
module asu #(parameter width = 2)(
|
||||||
input logic [0:0] op,
|
input logic [0:0] op,
|
||||||
input logic[2**width-1:0] A, input logic[2**width-1:0] B,
|
input logic[2**width-1:0] A, input logic[2**width-1:0] B,
|
||||||
output logic[2**width-1:0] OUT_1, output logic[0:0] COUT, output logic[0:0] OUT_CIN);
|
output logic[2**width-1:0] OUT_1, output logic[0:0] COUT, output logic[0:0] OUT_CIN
|
||||||
|
);
|
||||||
|
|
||||||
logic [2**width-1:0] operand;
|
logic [2**width-1:0] operand;
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
// A + (sub) ? B : -B
|
// A + (sub) ? B : -B
|
||||||
// Adds an extra bit to all operands to calculate the carry bit. Not optimal for hardware synthesis
|
// Adds an extra bit to all operands to calculate the carry bit. Not optimal for hardware synthesis
|
||||||
@@ -18,5 +20,6 @@ module asu #(parameter width = 2)(
|
|||||||
// Need to do this outside of the always_comb block because parameter-based bitslicing/indexing isn't supported?
|
// Need to do this outside of the always_comb block because parameter-based bitslicing/indexing isn't supported?
|
||||||
// Cin for final bit in adder to later be xor'ed with COUT to determine if a signed overflow occured for the MIPS architecture
|
// Cin for final bit in adder to later be xor'ed with COUT to determine if a signed overflow occured for the MIPS architecture
|
||||||
assign OUT_CIN = A[2**width-1] ^ operand[2**width-1] ^ OUT_1[2**width-1];
|
assign OUT_CIN = A[2**width-1] ^ operand[2**width-1] ^ OUT_1[2**width-1];
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
`endif
|
`endif
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
`ifndef CONTROL_UNIT_H
|
||||||
|
`define CONTROL_UNIT_H
|
||||||
|
`include "instruction_classifier.sv"
|
||||||
|
|
||||||
|
module control_unit (
|
||||||
|
input logic [5:0] op, input logic [5:0] func,
|
||||||
|
output logic [0:0] M2R, // Enables writing data stored in memory at the address (rs/A)+(ALU_SRC ? imm : rt/B) into rd
|
||||||
|
output logic [0:0] M2W, // Enable writing data stored in rt/B into memory at the address (rs/A)+(ALU_SRC ? imm : rt/B)
|
||||||
|
output logic [0:0] B, // AND'ed with flags to determine if branch is permitted
|
||||||
|
output logic [3:0] ALU_FN, // Controls what function the ALU is to perform
|
||||||
|
output logic [0:0] ALU_SRC, // Controls whether to use the rt/B register read port or 16-bit immediate
|
||||||
|
output logic [0:0] RDST, // Controls where to look in the instruction encoding for the register write address
|
||||||
|
output logic [0:0] RW // Enable register write port
|
||||||
|
);
|
||||||
|
logic [0:0] TYPE_R;
|
||||||
|
logic [0:0] TYPE_B1;
|
||||||
|
logic [0:0] TYPE_J;
|
||||||
|
logic [0:0] TYPE_B2;
|
||||||
|
logic [0:0] TYPE_I;
|
||||||
|
logic [0:0] TYPE_F;
|
||||||
|
logic [0:0] TYPE_M;
|
||||||
|
|
||||||
|
instruction_classifier CLASSIFIER (op, TYPE_R, TYPE_B1, TYPE_J, TYPE_B2, TYPE_I, TYPE_F, TYPE_M);
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
M2R = TYPE_M & op[3];
|
||||||
|
M2W = TYPE_M & ~op[3];
|
||||||
|
B = TYPE_B1 | TYPE_B2 | TYPE_J;
|
||||||
|
ALU_FN = (func & {(6){TYPE_R}}) | ( {4'b0000, op[1:0]} & {(6){TYPE_I}});
|
||||||
|
ALU_SRC = TYPE_B1 | TYPE_B2 | TYPE_I | TYPE_M;
|
||||||
|
RDST = TYPE_I; // Imm ops store back into rt
|
||||||
|
RW = TYPE_R | TYPE_I | (TYPE_M & op[3]); // All ALU R-type ops, Addi/Addiu ops, and memory loads
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
`endif
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
`ifndef INSTRUCTION_COUNTER_H
|
||||||
|
`define INSTRUCTION_COUNTER_H
|
||||||
|
|
||||||
|
module instruction_counter #(parameter width=5)(
|
||||||
|
input logic [0:0] clk, input logic [0:0] we,
|
||||||
|
input logic [2**width-1:0] W,
|
||||||
|
output logic [2**width-1:0] addr
|
||||||
|
);
|
||||||
|
|
||||||
|
logic [2**width-1:0] pc;
|
||||||
|
always_ff @(posedge clk) begin
|
||||||
|
if (we) begin
|
||||||
|
pc <= W;
|
||||||
|
end else begin
|
||||||
|
pc <= pc + 4;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign addr = pc;
|
||||||
|
endmodule
|
||||||
|
`endif
|
||||||
+3
-3
@@ -1,13 +1,13 @@
|
|||||||
`ifndef LU_H_SV
|
`ifndef LU_H_SV
|
||||||
`define LU_H_SV
|
`define LU_H_SV
|
||||||
module lu #(parameter width = 2) (
|
module lu #(parameter width = 2) (
|
||||||
input logic [1:0] op,
|
input logic [1:0] op, // 2 bit operand
|
||||||
input logic [2**width-1:0] A,
|
input logic [2**width-1:0] A, // width defined as 2^n
|
||||||
input logic [2**width-1:0] B,
|
input logic [2**width-1:0] B,
|
||||||
output logic [2**width-1:0] Y);
|
output logic [2**width-1:0] Y);
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
case (op)
|
case (op) // different operations of A and B based on operand
|
||||||
2'b00: Y = A & B;
|
2'b00: Y = A & B;
|
||||||
2'b01: Y = A | B;
|
2'b01: Y = A | B;
|
||||||
2'b10: Y = A ^ B;
|
2'b10: Y = A ^ B;
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
`include "assignment2.sv"
|
||||||
|
|
||||||
|
`define PRINT_REGISTERS(regs)\
|
||||||
|
$display("\tt0-t8: \t0x%0x 0x%0x 0x%0x 0x%0x 0x%0x 0x%0x 0x%0x 0x%0x\n\ts0-s8: \t0x%0x 0x%0x 0x%0x 0x%0x 0x%0x 0x%0x 0x%0x 0x%0x\n",\
|
||||||
|
regs[8], regs[9], regs[10], regs[11], regs[12], regs[13], regs[14], regs[15], \
|
||||||
|
regs[16], regs[17], regs[18], regs[19], regs[20], regs[21], regs[22], regs[23] \
|
||||||
|
);
|
||||||
|
`define TEST_CHECK(cond) if (cond) begin end else begin \
|
||||||
|
$display("Check %s failed\n", `"cond`"); \
|
||||||
|
`PRINT_REGISTERS(CPU.REGS.regs); \
|
||||||
|
num_errors += 1; \
|
||||||
|
end
|
||||||
|
|
||||||
|
module mips_tb(input logic [0:0] clk);
|
||||||
|
assignment2 #(5) CPU (clk);
|
||||||
|
|
||||||
|
integer num_errors = 0;
|
||||||
|
initial begin
|
||||||
|
// Zero out lower registers
|
||||||
|
$display("Beginning MIPS tests");
|
||||||
|
assign num_errors = 0;
|
||||||
|
|
||||||
|
for (integer N = 1; N < 32; ++N)
|
||||||
|
CPU.REGS.regs[N] = 32'd0;
|
||||||
|
|
||||||
|
// Check R-type / initialise
|
||||||
|
#1;
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[8] == 32'd0);
|
||||||
|
#1;
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[9] == (CPU.REGS.regs[8] + 32'd7));
|
||||||
|
|
||||||
|
// Check load-store
|
||||||
|
#1;
|
||||||
|
`TEST_CHECK(CPU.RAM.mem[0] == CPU.REGS.regs[9]);
|
||||||
|
#1;
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[10] == CPU.RAM.mem[0]);
|
||||||
|
|
||||||
|
// Check arithmetic
|
||||||
|
#1;
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[11] == (CPU.REGS.regs[9] + CPU.REGS.regs[10]));
|
||||||
|
#1;
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[12] == (CPU.REGS.regs[9] - CPU.REGS.regs[11]));
|
||||||
|
#1;
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[13] == (CPU.REGS.regs[9] + 3));
|
||||||
|
#1;
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[14] == (CPU.REGS.regs[12] + CPU.REGS.regs[13]));
|
||||||
|
|
||||||
|
// Check logic instructions
|
||||||
|
#1;
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[16] == (CPU.REGS.regs[9] & CPU.REGS.regs[13]));
|
||||||
|
#1;
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[17] == (CPU.REGS.regs[9] | CPU.REGS.regs[13]));
|
||||||
|
#1;
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[18] == (CPU.REGS.regs[9] ^ CPU.REGS.regs[13]));
|
||||||
|
#1;
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[19] == ( ~(CPU.REGS.regs[9] | CPU.REGS.regs[13]) ));
|
||||||
|
|
||||||
|
// Check SLT instructions
|
||||||
|
#1;
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[20] == $signed(CPU.REGS.regs[12]) < $signed(CPU.REGS.regs[14]));
|
||||||
|
#1;
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[21] == $unsigned(CPU.REGS.regs[12]) < $unsigned(CPU.REGS.regs[14]));
|
||||||
|
|
||||||
|
// Check loop branching
|
||||||
|
for (integer N = 1; N < 11; ++N) begin
|
||||||
|
#1;
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[0] == 32'(N));
|
||||||
|
#1;
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[22] == $unsigned(CPU.REGS.regs[8]) < $unsigned(CPU.REGS.regs[13]));
|
||||||
|
end
|
||||||
|
|
||||||
|
// Final state check
|
||||||
|
#1;
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[8] == 32'd10);
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[9] == 32'd7);
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[10] == 32'd7);
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[11] == 32'd14);
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[12] == -32'sd7);
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[13] == 32'd10);
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[14] == 32'd3);
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[15] == 32'd0);
|
||||||
|
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[16] == 32'd2);
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[17] == 32'd15);
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[18] == 32'd13);
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[19] == -32'sd16);
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[20] == 32'd1);
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[21] == 32'd0);
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[22] == 32'd0);
|
||||||
|
`TEST_CHECK(CPU.REGS.regs[23] == 32'd0);
|
||||||
|
|
||||||
|
if (num_errors == 0) $display("\x1b[38;5;10mAll MIPS tests passing\x1b[m");
|
||||||
|
else $display("\x1b[38;5;9m%0d MIPS test(s) failing\x1b[m", num_errors);
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
`ifndef RAM_H
|
||||||
|
`define RAM_H
|
||||||
|
|
||||||
|
module ram #(addrwidth=9, datawidth=5)(
|
||||||
|
input logic [0:0] clk,
|
||||||
|
input logic [2**addrwidth-1:0] addr,
|
||||||
|
input logic [0:0] we,
|
||||||
|
input logic [datawidth-1:0] data_in,
|
||||||
|
output logic [datawidth-1:0] data_out
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO: Make this byte-sized, NOT word-sized!
|
||||||
|
logic [2**datawidth-1:0] mem[(2**(addrwidth+$clog2(datawidth)-3))-1:0];
|
||||||
|
|
||||||
|
// NOTE: Possible issue with assignments still pending by end of initial block
|
||||||
|
initial begin
|
||||||
|
for (integer ADDR = 0; ADDR < 2**(addrwidth+$clog2(datawidth)-3); ++ADDR) begin
|
||||||
|
mem[ADDR] <= 8'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge clk) begin
|
||||||
|
if (we) begin
|
||||||
|
mem[addr] <= data_in;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
assign data_out = mem[addr];
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
`endif
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
`ifndef REGISTER_FILE_H
|
||||||
|
`define REGISTER_FILE_H
|
||||||
|
|
||||||
|
module register_file #(parameter width=5, parameter nregs=5)(
|
||||||
|
input logic [0:0] clk, input logic[0:0] we,
|
||||||
|
input logic [nregs-1:0] WA, input logic [2**width-1:0] WD,
|
||||||
|
input logic [nregs-1:0] RA1, output logic [2**width-1:0] RD1,
|
||||||
|
input logic [nregs-1:0] RA2, output logic [2**width-1:0] RD2,
|
||||||
|
output logic [2**width-1:0] regs_out [2**nregs]
|
||||||
|
);
|
||||||
|
localparam BW = 2**width;
|
||||||
|
logic [2**width-1:0] regs[2**nregs];
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
regs[0] = {(2**width){1'b0}};
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge clk) begin
|
||||||
|
if (we & (WA != {(2**width){1'b0}} )) begin
|
||||||
|
regs[WA] <= WD;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign RD1 = regs[RA1];
|
||||||
|
assign RD2 = regs[RA2];
|
||||||
|
assign regs_out = regs; // Expose registers externally
|
||||||
|
endmodule
|
||||||
|
`endif
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
`ifndef ROM_H
|
||||||
|
`define ROM_H
|
||||||
|
|
||||||
|
module rom #(parameter m=7,p=4) (
|
||||||
|
input logic [m-1:0] Ad,
|
||||||
|
output logic [p-1:0] Dout
|
||||||
|
);
|
||||||
|
|
||||||
|
logic [p-1:0] mem[2**m-1:0];
|
||||||
|
assign Dout = mem[Ad];
|
||||||
|
|
||||||
|
//Load the program in memory
|
||||||
|
// The machine code stored in text file program.dat written in Hex format
|
||||||
|
initial begin
|
||||||
|
`ifdef QUARTUS_SYNTH
|
||||||
|
$readmemh("../../asm/bin/ELEC4720-2026s2-Ass-02-Demo.txt",mem); //$readmemb for binary
|
||||||
|
`else
|
||||||
|
$readmemh("./asm/bin/ELEC4720-2026s2-Ass-02-Demo.txt",mem); //$readmemb for binary
|
||||||
|
`endif
|
||||||
|
end
|
||||||
|
endmodule // end rom module
|
||||||
|
|
||||||
|
`endif
|
||||||
|
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
`ifndef SEVEN_SEG_4_H_SV
|
||||||
|
`define SEVEN_SEG_4_H_SV
|
||||||
|
|
||||||
|
`include "seven_seg.sv"
|
||||||
|
module seven_seg_4digit (
|
||||||
|
input logic [15:0] num,
|
||||||
|
output logic [7:0] segments0,
|
||||||
|
output logic [7:0] segments1,
|
||||||
|
output logic [7:0] segments2,
|
||||||
|
output logic [7:0] segments3
|
||||||
|
);
|
||||||
|
|
||||||
|
// Rightmost digit
|
||||||
|
seven_seg digit0 (
|
||||||
|
.num(num[3:0]),
|
||||||
|
.rbi_inv(1'b0),
|
||||||
|
.segments(segments0)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Second digit from right
|
||||||
|
seven_seg digit1 (
|
||||||
|
.num(num[7:4]),
|
||||||
|
.rbi_inv(1'b0),
|
||||||
|
.segments(segments1)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Third digit from right
|
||||||
|
seven_seg digit2 (
|
||||||
|
.num(num[11:8]),
|
||||||
|
.rbi_inv(1'b0),
|
||||||
|
.segments(segments2)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Leftmost digit
|
||||||
|
seven_seg digit3 (
|
||||||
|
.num(num[15:12]),
|
||||||
|
.rbi_inv(1'b0),
|
||||||
|
.segments(segments3)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
`endif
|
||||||
|
|
||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
module shifter #(width=2)(input logic [2:0] op,
|
module shifter #(width=2)(input logic [2:0] op,
|
||||||
input logic[2**width-1:0] A, input logic[2**width-1:0] B, input logic[width-1:0] C,
|
input logic[2**width-1:0] A, input logic[2**width-1:0] B, input logic[width-1:0] C,
|
||||||
output logic[2**width-1:0] OUT_1);
|
output logic[2**width-1:0] OUT_1);
|
||||||
|
// A and B are 2^n bits wide and C is n bits wide as according to the docs
|
||||||
always_comb begin
|
always_comb begin
|
||||||
case (op)
|
case (op)
|
||||||
3'b000: OUT_1 = A << C;
|
3'b000: OUT_1 = A << C;
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
`ifndef SIGN_EXTENDER_H
|
||||||
|
`define SIGN_EXTENDER_H
|
||||||
|
|
||||||
|
module sign_extender #(in_width=4, out_width=5)(
|
||||||
|
input logic [0:0] op,
|
||||||
|
input logic [2**in_width-1:0] val,
|
||||||
|
output logic [2**out_width-1:0] ext_val
|
||||||
|
);
|
||||||
|
always_comb begin
|
||||||
|
if (op) begin
|
||||||
|
ext_val = { {(2**(out_width-in_width)){val[2**in_width-1]}}, val};
|
||||||
|
end else begin
|
||||||
|
ext_val = ({{(2**(out_width-in_width)){1'b0}}, val});
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
`endif
|
||||||
Reference in new issue
Block a user