Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions rtl/alu.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/* Copyright (c) 2024 Maveric NU. All rights reserved. */

// --------------------------------------
// This is a Arithmetic Logic Unit (ALU).
// --------------------------------------

module alu
(
input [ 2:0 ] select,
input [ 15:0 ] in_a,
input [ 15:0 ] in_b,
output [ 15:0 ] alu_out
);

reg [ 15:0 ] res;

parameter ADD = 3'b000;
parameter SUB = 3'b001;
parameter AND = 3'b010;
parameter OR = 3'b011;
parameter XOR = 3'b100;
parameter SHL = 3'b101;
parameter SHR = 3'b110;
parameter CMP = 3'b111;

always @(*) begin
case ( select )
ADD : res = in_a + in_b;
SUB : res = in_a - in_b;
AND : res = in_a & in_b;
OR : res = in_a | in_b;
XOR : res = in_a ^ in_b;
SHL : res = in_a << ( in_b % 16 );
SHR : res = in_a >> ( in_b % 16 );
CMP : begin
if ( in_a == in_b ) begin
res = 0;
end
else if ( in_a > in_b ) begin
res = 1;
end
else begin
res = 2;
end
end
default: res = 16'h0000; // Default value as 16-bit zero
endcase
end

assign alu_out = res;

endmodule
56 changes: 56 additions & 0 deletions rtl/branch_logic.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/* Copyright (c) 2024 Maveric NU. All rights reserved. */

// --------------------------------------
// This is a Branch Logic.
// --------------------------------------


module branch_logic
(
input [ 7:0] address,
/* verilator lint_off UNUSED */
input [ 15:0] instruction,
input [ 15:0] last_alu_result,
output reg [ 7:0] new_pc
);

wire [ 1:0] branch_cond;
wire [ 7:0] immediate;
wire [ 1:0] format;

assign branch_cond = instruction[ 3:2 ];
assign immediate = instruction[ 11:4 ];
assign format = instruction[ 1:0 ];

always @(*) begin
if (format == 2'b10) begin
case (branch_cond)
2'b00: begin
if (last_alu_result == 0)
new_pc = immediate;
else
new_pc = address + 8'b00000001;
end
2'b01: begin
if (last_alu_result == 1)
new_pc = immediate;
else
new_pc = address + 8'b00000001;
end
2'b10: begin
if (last_alu_result == 2)
new_pc = immediate;
else
new_pc = address + 8'b00000001;
end
default: begin
new_pc = address + 8'b00000001;
end
endcase
end
else begin
new_pc = address + 8'b00000001;
end
end

endmodule
158 changes: 158 additions & 0 deletions rtl/cpu.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/* Copyright (c) 2024 Maveric NU. All rights reserved. */

// --------------------------------------
// This is a Control Unit (CU).
// --------------------------------------


module cpu
(
input clk,
input run,
input reset,
input [15:0] d_inst,
input ls_done,

output reg [ 3:0] mux_sel,
output reg done,
output reg [ 2:0] sel,
output reg sel_reg_c,
output reg en_s,
output reg en_c,
output reg [ 1:0] en_ls,
output reg [ 7:0] en,
output reg en_inst,
output reg [15:0] im_d
);

parameter S0 = 2'b00;
parameter S1 = 2'b01;
parameter S2 = 2'b10;

reg [ 1:0] cur_state;
reg [ 1:0] next_state;
wire [ 1:0] format;
wire ls_flag;

assign format = d_inst[ 1:0 ];
assign ls_flag = d_inst[ 2 ];

// Next state sequential logic
always @(posedge clk) begin
if (!reset) begin
cur_state <= S0;
end
else begin
cur_state <= next_state;
end
end

always @(*) begin
en_inst = 1;
en_s = 0;
en_c = 0;
done = 0;
mux_sel = 4'b1001;
sel = 3'b0;
en = 8'b0;
im_d = { 8'b0, d_inst[ 12:5 ] };
sel_reg_c = 1'b0;
en_ls = 2'b00;

case (cur_state)
S0: begin
if (format != 2'b10) begin
en_s = 1;
mux_sel = { 1'b0, d_inst[ 15:13 ] };
if (format == 2'b01) begin
im_d = { 8'b0, d_inst[ 12:5 ] };
end
end
sel = 3'b0;
done = 0;
en_inst = 1;
end

S1: begin
if (format != 2'b10) begin
if (format == 2'b00 | format == 2'b11) begin
mux_sel = { 1'b0, d_inst[ 12:10 ] };
end
else if (format == 2'b01) begin
mux_sel = 4'b1000;
end
else begin
mux_sel = 4'b1001;
end
sel = d_inst[ 4:2 ];
end
else begin
sel = 3'b0;
mux_sel = 4'b1001;
end

if (format == 2'b11) begin
en_ls = (ls_flag == 0) ? 2'b01 : 2'b10;
end

// LSU d_out loaded to reg C
if (format == 2'b11) begin
sel_reg_c = 1'b1;
end
en_c = 1'b1;
en_inst = 0;
done = 0;
end

S2: begin
if (format != 2'b10 & format != 2'b11) begin
en[ d_inst[ 15:13 ] ] = 1;
end
else if (format == 2'b11 & ls_flag == 0) begin
en[ d_inst[ 15:13 ] ] = 1;
end
else begin
en = 8'b0;
end
sel = 3'b0;
done = 1'b1;
en_inst = 1;
end

default: begin
en_s = 0;
en_c = 0;
done = 0;
mux_sel = 4'b1001;
sel = 3'b0;
en = 8'b0;
en_ls = 2'b00;
end
endcase
end

// Next state combinational logic
always @(*) begin
case (cur_state)
S0: begin
if (run == 1) begin
next_state = (format == 2'b10) ? S2 : S1;
end
else begin
next_state = S0;
end
end
S1: begin
if (format == 2'b11) begin
next_state = (ls_done == 1) ? S2 : S1;
end
else begin
next_state = (en_c == 1) ? S2 : S1;
end
end
S2: next_state = (done == 1) ? S0 : S2;
default: next_state = S0;
endcase
end

endmodule
20 changes: 20 additions & 0 deletions rtl/dff_module.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module dff_module
(
input clk,
input en,
input wire [ 15:0] d_in,
input reset,

output reg [ 15:0] mux_out
);

always @(posedge clk) begin
if (!reset) begin
mux_out <= 16'b0;
end
else if (en) begin
mux_out <= d_in;
end
end

endmodule
35 changes: 35 additions & 0 deletions rtl/mux.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module mux
(
input [ 15:0 ] reg0,
input [ 15:0 ] reg1,
input [ 15:0 ] reg2,
input [ 15:0 ] reg3,
input [ 15:0 ] reg4,
input [ 15:0 ] reg5,
input [ 15:0 ] reg6,
input [ 15:0 ] reg7,
input [ 15:0 ] im_d,
input [ 15:0 ] def_val,

input [ 3:0 ] mux_sel,
output reg [ 15:0 ] mux_out
);

always @(*) begin
case ( mux_sel )
4'b0000: mux_out = reg0;
4'b0001: mux_out = reg1;
4'b0010: mux_out = reg2;
4'b0011: mux_out = reg3;
4'b0100: mux_out = reg4;
4'b0101: mux_out = reg5;
4'b0110: mux_out = reg6;
4'b0111: mux_out = reg7;
4'b1000: mux_out = im_d;
4'b1001: mux_out = def_val;

default: mux_out = 16'b0;
endcase
end

endmodule
20 changes: 20 additions & 0 deletions rtl/pc.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module pc
(
input clk,
input en_pc,
input reset,
input [7:0] d_in,

output reg [7:0] d_out
);

always @(posedge clk) begin
if (!reset) begin
d_out <= 8'b0;
end
else if (en_pc) begin
d_out <= d_in;
end
end

endmodule
Loading