RISC-V base implementation #1
20
rtl/alu.v
20
rtl/alu.v
|
@ -1,18 +1,18 @@
|
||||||
module alu (input [31:0] input_a, input_b,
|
module alu (input [31:0] in_a, in_b,
|
||||||
input [3:0] op_code,
|
input [3:0] op_code,
|
||||||
output reg [31:0] out);
|
output reg [31:0] out);
|
||||||
|
|
||||||
always@ (*) begin
|
always@ (*) begin
|
||||||
case (op_code)
|
case (op_code)
|
||||||
4'b0000 : out <= input_a + input_b;
|
4'b0000 : out <= in_a + in_b;
|
||||||
4'b0001 : out <= input_a - input_b;
|
4'b0001 : out <= in_a - in_b;
|
||||||
4'b0010 : out <= input_a << input_b;
|
4'b0010 : out <= in_a << in_b;
|
||||||
4'b0011 : out <= (input_a < input_b) ? 1 : 0;
|
4'b0011 : out <= (in_a < in_b) ? 1 : 0;
|
||||||
4'b0100 : out <= input_a ^ input_b;
|
4'b0100 : out <= in_a ^ in_b;
|
||||||
4'b0101 : out <= input_a >> input_b;
|
4'b0101 : out <= in_a >> in_b;
|
||||||
4'b0111 : out <= input_a >>> input_b;
|
4'b0111 : out <= in_a >>> in_b;
|
||||||
4'b1000 : out <= input_a | input_b;
|
4'b1000 : out <= in_a | in_b;
|
||||||
4'b1001 : out <= input_a & input_b;
|
4'b1001 : out <= in_a & in_b;
|
||||||
default : out <= 32'b0;
|
default : out <= 32'b0;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
|
@ -30,20 +30,3 @@ module instruction (input [31:0] address,
|
||||||
assign instruction = memory[address];
|
assign instruction = memory[address];
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
// -- result(1) := "00000000001100110000010000010000";
|
|
||||||
|
|
||||||
// -- "000000000000_00000_000_00110_0010000"
|
|
||||||
// result(0) := "00000000000100000000001100010000";
|
|
||||||
// -- "000000000001_00000_000_00111_0010000"
|
|
||||||
// result(1) := "00000000000000000000001110010000";
|
|
||||||
|
|
||||||
// -- "000000000000_00110_000_01000_0010000"
|
|
||||||
// result(2) := "00000000000000110000010000010000";
|
|
||||||
// -- "0000000_00111_00110_000_00110_0110000"
|
|
||||||
// result(3) := "00000000011100110000001100110000";
|
|
||||||
// -- "000000000000_01000_000_00111_0010000"
|
|
||||||
// result(4) := "00000000000001000000001110010000";
|
|
||||||
|
|
||||||
// -- 111111111111_11111_110_00111_1101100
|
|
||||||
// result(5) := "11111111111111111101001111101100";
|
|
|
@ -1,8 +1,8 @@
|
||||||
module mux2_1 #(parameter BUS_SIZE = 32)
|
module mux2_1 #(parameter BUS_SIZE = 32)
|
||||||
(input [BUS_SIZE - 1:0] A, B,
|
(input [BUS_SIZE - 1:0] in_1, in_2,
|
||||||
input S,
|
input sel,
|
||||||
output [BUS_SIZE - 1:0] O);
|
output [BUS_SIZE - 1:0] out);
|
||||||
|
|
||||||
assign O = S ? B : A;
|
assign out = sel ? in_2 : in_1;
|
||||||
|
|
||||||
endmodule
|
endmodule
|
10
rtl/mux4_1.v
10
rtl/mux4_1.v
|
@ -1,9 +1,9 @@
|
||||||
module mux4_1 #(parameter BUS_SIZE = 32)
|
module mux4_1 #(parameter BUS_SIZE = 32)
|
||||||
(input [BUS_SIZE - 1:0] A, B, C, D,
|
(input [BUS_SIZE - 1:0] in_1, in_2, in_3, in_4,
|
||||||
input [1:0] S,
|
input [1:0] sel,
|
||||||
output [BUS_SIZE - 1:0] O);
|
output [BUS_SIZE - 1:0] out);
|
||||||
|
|
||||||
assign O = S[1] ? (S[0] ? D : C)
|
assign out = sel[1] ? (sel[0] ? in_4 : in_3)
|
||||||
: (S[0] ? B : A);
|
: (sel[0] ? in_2 : in_1);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
module risc_v_cpu (input clock, reset, output [31:0] out);
|
module risc_v_cpu (input clock, reset,
|
||||||
|
output [31:0] out);
|
||||||
|
|
||||||
wire [31:0] instruction;
|
wire [31:0] instruction;
|
||||||
|
|
||||||
|
@ -48,34 +49,34 @@ module risc_v_cpu (input clock, reset, output [31:0] out);
|
||||||
.data_out_b(reg_data_out_b)
|
.data_out_b(reg_data_out_b)
|
||||||
);
|
);
|
||||||
|
|
||||||
mux2_1 mux2_1_1 (
|
mux2_1 mux2_alu_in_b (
|
||||||
.A(reg_data_out_b),
|
.in_1(reg_data_out_b),
|
||||||
.B(imm),
|
.in_2(imm),
|
||||||
.S(alu_src),
|
.sel(alu_src),
|
||||||
.O(alu_in_b)
|
.out(alu_in_b)
|
||||||
);
|
);
|
||||||
|
|
||||||
alu alu (
|
alu alu (
|
||||||
.input_a(reg_data_out_a),
|
.in_a(reg_data_out_a),
|
||||||
.input_b(alu_in_b),
|
.in_b(alu_in_b),
|
||||||
.op_code(alu_func),
|
.op_code(alu_func),
|
||||||
.out(alu_out)
|
.out(alu_out)
|
||||||
);
|
);
|
||||||
|
|
||||||
mux2_1 #(2) mux2_1_2 (
|
mux2_1 #(2) mux2_pc_sel_branch (
|
||||||
.A(pc_is_branch),
|
.in_1(pc_is_branch),
|
||||||
.B({alu_out[1], (alu_not ? ~alu_out[0] : alu_out[0])}),
|
.in_2({alu_out[1], (alu_not ? ~alu_out[0] : alu_out[0])}),
|
||||||
.S(pc_is_jmp),
|
.sel(pc_is_jmp),
|
||||||
.O(pc_sel_in)
|
.out(pc_sel_in)
|
||||||
);
|
);
|
||||||
|
|
||||||
mux4_1 mux4_1_1 (
|
mux4_1 mux4_pc_sel_in (
|
||||||
.A(pc_addr + 4),
|
.in_1(pc_addr + 4),
|
||||||
.B(pc_addr + imm),
|
.in_2(pc_addr + imm),
|
||||||
.C(alu_out),
|
.in_3(alu_out),
|
||||||
.D(0),
|
.in_4(0),
|
||||||
.S(pc_sel_in),
|
.sel(pc_sel_in),
|
||||||
.O(pc_new_addr)
|
.out(pc_new_addr)
|
||||||
);
|
);
|
||||||
|
|
||||||
program_counter program_counter (
|
program_counter program_counter (
|
||||||
|
@ -99,13 +100,13 @@ module risc_v_cpu (input clock, reset, output [31:0] out);
|
||||||
.data_out(mem_out)
|
.data_out(mem_out)
|
||||||
);
|
);
|
||||||
|
|
||||||
mux4_1 mux4_1_2 (
|
mux4_1 mux4_reg_sel_data_in (
|
||||||
.A(alu_out),
|
.in_1(alu_out),
|
||||||
.B(mem_out),
|
.in_2(mem_out),
|
||||||
.C(pc_addr + 4),
|
.in_3(pc_addr + 4),
|
||||||
.D(pc_addr + alu_out),
|
.in_4(pc_addr + alu_out),
|
||||||
.S(reg_sel_data_in),
|
.sel(reg_sel_data_in),
|
||||||
.O(reg_data_in)
|
.out(reg_data_in)
|
||||||
);
|
);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
25
tb/tb_alu.v
25
tb/tb_alu.v
|
@ -1,27 +1,22 @@
|
||||||
`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
module tb_alu ();
|
module tb_alu ();
|
||||||
// Design Inputs and outputs
|
reg [31:0] in_a;
|
||||||
reg [31:0] in_a;
|
reg [31:0] in_b;
|
||||||
reg [31:0] in_b;
|
reg [2:0] op_code;
|
||||||
reg [2:0] op_code;
|
wire [31:0] out;
|
||||||
wire [31:0] out;
|
|
||||||
|
|
||||||
// DUT instantiation
|
alu alu (
|
||||||
alu alu (
|
.in_a(in_a),
|
||||||
.input_a(in_a),
|
.in_b(in_b),
|
||||||
.input_b(in_b),
|
|
||||||
.op_code(op_code),
|
.op_code(op_code),
|
||||||
.out(out)
|
.out(out)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Test stimulus
|
initial begin
|
||||||
initial begin
|
|
||||||
// Use the monitor task to display the FPGA IO
|
|
||||||
$monitor("time=%3d, in_a=%d, in_b=%d, ctrl=%b, q=%d \n",
|
$monitor("time=%3d, in_a=%d, in_b=%d, ctrl=%b, q=%d \n",
|
||||||
$time, in_a, in_b, op_code, out);
|
$time, in_a, in_b, op_code, out);
|
||||||
|
|
||||||
// Generate each input with a 20 ns delay between them
|
|
||||||
in_a = 1'b0;
|
in_a = 1'b0;
|
||||||
in_b = 1'b0;
|
in_b = 1'b0;
|
||||||
op_code = 3'b000;
|
op_code = 3'b000;
|
||||||
|
@ -36,6 +31,6 @@ initial begin
|
||||||
op_code = 3'b001;
|
op_code = 3'b001;
|
||||||
#20
|
#20
|
||||||
if (out !== 2) $display("[FAILED] output should be 2");
|
if (out !== 2) $display("[FAILED] output should be 2");
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule : tb_alu
|
endmodule : tb_alu
|
||||||
|
|
|
@ -1,44 +1,22 @@
|
||||||
`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
module tb_mux2_1 ();
|
module tb_mux2_1 ();
|
||||||
// Clock and reset signals
|
reg ctrl;
|
||||||
reg clk;
|
reg [31:0] in_a;
|
||||||
reg reset;
|
reg [31:0] in_b;
|
||||||
|
wire [31:0] out;
|
||||||
|
|
||||||
// Design Inputs and outputs
|
mux2_1 mux (
|
||||||
reg [31:0] in_a;
|
|
||||||
reg [31:0] in_b;
|
|
||||||
reg ctrl;
|
|
||||||
wire [31:0] out;
|
|
||||||
|
|
||||||
// DUT instantiation
|
|
||||||
mux2_1 mux (
|
|
||||||
.S(ctrl),
|
.S(ctrl),
|
||||||
.A(in_a),
|
.A(in_a),
|
||||||
.B(in_b),
|
.B(in_b),
|
||||||
.O(out)
|
.O(out)
|
||||||
);
|
);
|
||||||
|
|
||||||
// generate the clock
|
initial begin
|
||||||
initial begin
|
|
||||||
clk = 1'b0;
|
|
||||||
// forever #1 clk = ~clk;
|
|
||||||
end
|
|
||||||
|
|
||||||
// Generate the reset
|
|
||||||
initial begin
|
|
||||||
reset = 1'b1;
|
|
||||||
#10
|
|
||||||
reset = 1'b0;
|
|
||||||
end
|
|
||||||
|
|
||||||
// Test stimulus
|
|
||||||
initial begin
|
|
||||||
// Use the monitor task to display the FPGA IO
|
|
||||||
$monitor("time=%3d, in_a=%d, in_b=%d, ctrl=%b, q=%d \n",
|
$monitor("time=%3d, in_a=%d, in_b=%d, ctrl=%b, q=%d \n",
|
||||||
$time, in_a, in_b, ctrl, out);
|
$time, in_a, in_b, ctrl, out);
|
||||||
|
|
||||||
// Generate each input with a 20 ns delay between them
|
|
||||||
in_a = 1'b0;
|
in_a = 1'b0;
|
||||||
in_b = 1'b0;
|
in_b = 1'b0;
|
||||||
ctrl = 1'b0;
|
ctrl = 1'b0;
|
||||||
|
@ -56,6 +34,6 @@ initial begin
|
||||||
in_a = 1'b1;
|
in_a = 1'b1;
|
||||||
#20
|
#20
|
||||||
if (out !== 1) $display("[FAILED] output should be 1");
|
if (out !== 1) $display("[FAILED] output should be 1");
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule : tb_mux2_1
|
endmodule : tb_mux2_1
|
||||||
|
|
|
@ -1,36 +1,28 @@
|
||||||
`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
module tb_risc_v_cpu ();
|
module tb_risc_v_cpu ();
|
||||||
integer i;
|
reg clk;
|
||||||
|
reg reset;
|
||||||
|
integer i;
|
||||||
|
wire [31:0] out;
|
||||||
|
|
||||||
// Clock and reset signals
|
risc_v_cpu risc_v_cpu (
|
||||||
reg clk;
|
|
||||||
reg reset;
|
|
||||||
|
|
||||||
// Design Inputs and outputs
|
|
||||||
wire [31:0] out;
|
|
||||||
|
|
||||||
// DUT instantiation
|
|
||||||
risc_v_cpu risc_v_cpu (
|
|
||||||
.clock(clk),
|
.clock(clk),
|
||||||
.reset(reset),
|
.reset(reset),
|
||||||
.out(out)
|
.out(out)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Generate the reset
|
initial begin
|
||||||
initial begin
|
|
||||||
reset = 1'b1;
|
reset = 1'b1;
|
||||||
#10
|
#10
|
||||||
reset = 1'b0;
|
reset = 1'b0;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
initial begin
|
||||||
// generate the clock
|
|
||||||
initial begin
|
|
||||||
clk = 1'b0;
|
clk = 1'b0;
|
||||||
for (i = 0; i < 100; i = i + 1) begin
|
for (i = 0; i < 100; i = i + 1) begin
|
||||||
#1 clk = ~clk;
|
#1 clk = ~clk;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule : tb_risc_v_cpu
|
endmodule : tb_risc_v_cpu
|
||||||
|
|
Loading…
Reference in New Issue