Add: basic element for risc-v single cycle cpu
This commit is contained in:
parent
0e72c3a2e6
commit
b3fd2a827d
23
rtl/alu.v
23
rtl/alu.v
|
@ -1,6 +1,19 @@
|
||||||
module alu (S, A, B);
|
module alu (input [31:0] input_a, input_b,
|
||||||
output [31:0] S;
|
input [2:0] op_code,
|
||||||
input [31:0] A, B;
|
output reg [31:0] out);
|
||||||
|
|
||||||
|
always@ (*) begin
|
||||||
|
case (op_code)
|
||||||
|
3'b000 : out <= input_a + input_b;
|
||||||
|
3'b001 : out <= input_a << input_b;
|
||||||
|
3'b010 : out <= (input_a < input_b) ? 1 : 0;
|
||||||
|
3'b011 : out <= input_a ^ input_b;
|
||||||
|
3'b100 : out <= input_a >> input_b;
|
||||||
|
3'b101 : out <= input_a >>> input_b;
|
||||||
|
3'b110 : out <= input_a | input_b;
|
||||||
|
3'b111 : out <= input_a & input_b;
|
||||||
|
default : out <= 32'b0;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
xor N[31:0] (S, A, B);
|
endmodule
|
||||||
endmodule
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
module decoder (input [31:0] instruction,
|
||||||
|
output immediate,
|
||||||
|
output we_reg, adder_pc,
|
||||||
|
output [1:0] input_reg,
|
||||||
|
output [4:0] select_a, select_b, select_d,
|
||||||
|
output source_alu,
|
||||||
|
output [2:0] op_code_alu,
|
||||||
|
output mem_we,
|
||||||
|
output [31:0] mem_address
|
||||||
|
output jmp_pc, b_pc);
|
||||||
|
|
||||||
|
always @(*) begin
|
||||||
|
if (reset == 1)
|
||||||
|
registers[0] <= 32'b0;
|
||||||
|
else if (we == 1)
|
||||||
|
registers[select_d] <= input_d;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,8 @@
|
||||||
|
module instruction (input [31:0] address,
|
||||||
|
output [31:0] instruction);
|
||||||
|
|
||||||
|
reg [63:0] memory [31:0];
|
||||||
|
|
||||||
|
assign instruction = memory[address];
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,18 @@
|
||||||
|
module instruction (input clock, reset,
|
||||||
|
input we,
|
||||||
|
input [31:0] address,
|
||||||
|
input [31:0] data_in
|
||||||
|
output [31:0] data_out);
|
||||||
|
|
||||||
|
reg [63:0] memory [31:0];
|
||||||
|
|
||||||
|
always @(posedge clock, reset) begin
|
||||||
|
if (reset == 1)
|
||||||
|
memory[0] <= 32'b0;
|
||||||
|
else if (we == 1)
|
||||||
|
memory[address] <= data_in;
|
||||||
|
end
|
||||||
|
|
||||||
|
assign data_out = memory[address];
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,7 @@
|
||||||
|
module mux2_1 (input [31:0] A, B,
|
||||||
|
input S,
|
||||||
|
output [31:0] O);
|
||||||
|
|
||||||
|
assign O = S ? B : A;
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,8 @@
|
||||||
|
module mux4_1 (input [31:0] A, B, C, D,
|
||||||
|
input [1:0] S,
|
||||||
|
output [31:0] O);
|
||||||
|
|
||||||
|
assign O = S[0] ? (S[1] ? D : C)
|
||||||
|
: (S[1] ? B : A);
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,12 @@
|
||||||
|
module program_counter (input clock, reset,
|
||||||
|
input [31:0] new_pc,
|
||||||
|
output reg [31:0] pc);
|
||||||
|
|
||||||
|
always @ (posedge clock, reset) begin
|
||||||
|
if (reset == 1)
|
||||||
|
pc <= 32'b0;
|
||||||
|
else
|
||||||
|
pc <= new_pc;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,18 @@
|
||||||
|
module registers_bank (input clock, reset, we,
|
||||||
|
input [4:0] select_d, select_a, select_b,
|
||||||
|
input [31:0] input_d,
|
||||||
|
output [31:0] output_a, output_b);
|
||||||
|
|
||||||
|
reg [31:0] registers[31:0];
|
||||||
|
|
||||||
|
always @(posedge clock, reset) begin
|
||||||
|
if (reset == 1)
|
||||||
|
registers[0] <= 32'b0;
|
||||||
|
else if (we == 1)
|
||||||
|
registers[select_d] <= input_d;
|
||||||
|
end
|
||||||
|
|
||||||
|
assign output_a = registers[select_a];
|
||||||
|
assign output_b = registers[select_b];
|
||||||
|
|
||||||
|
endmodule
|
|
@ -33,5 +33,3 @@ add wave -radix unsigned *' >> ./sim/simu.do
|
||||||
echo 'run -all' >> ./sim/simu.do
|
echo 'run -all' >> ./sim/simu.do
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|
||||||
# CRC - Hamming Code
|
|
||||||
|
|
44
tb/tb_alu.v
44
tb/tb_alu.v
|
@ -1,3 +1,41 @@
|
||||||
module tb_alu (S);
|
`timescale 1ns / 1ps
|
||||||
output [31:0] S;
|
|
||||||
endmodule
|
module tb_alu ();
|
||||||
|
// Design Inputs and outputs
|
||||||
|
reg [31:0] in_a;
|
||||||
|
reg [31:0] in_b;
|
||||||
|
reg [2:0] op_code;
|
||||||
|
wire [31:0] out;
|
||||||
|
|
||||||
|
// DUT instantiation
|
||||||
|
alu alu (
|
||||||
|
.input_a(in_a),
|
||||||
|
.input_b(in_b),
|
||||||
|
.op_code(op_code),
|
||||||
|
.out(out)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 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",
|
||||||
|
$time, in_a, in_b, op_code, out);
|
||||||
|
|
||||||
|
// Generate each input with a 20 ns delay between them
|
||||||
|
in_a = 1'b0;
|
||||||
|
in_b = 1'b0;
|
||||||
|
op_code = 3'b000;
|
||||||
|
#20
|
||||||
|
if (out !== 0) $display("[FAILED] output should be 0");
|
||||||
|
in_a = 1'b1;
|
||||||
|
#20
|
||||||
|
if (out !== 1) $display("[FAILED] output should be 1");
|
||||||
|
in_b = 1'b1;
|
||||||
|
#20
|
||||||
|
if (out !== 2) $display("[FAILED] output should be 2");
|
||||||
|
op_code = 3'b001;
|
||||||
|
#20
|
||||||
|
if (out !== 2) $display("[FAILED] output should be 2");
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule : tb_alu
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
|
module tb_mux2_1 ();
|
||||||
|
// Clock and reset signals
|
||||||
|
reg clk;
|
||||||
|
reg reset;
|
||||||
|
|
||||||
|
// Design Inputs and outputs
|
||||||
|
reg [31:0] in_a;
|
||||||
|
reg [31:0] in_b;
|
||||||
|
reg ctrl;
|
||||||
|
wire [31:0] out;
|
||||||
|
|
||||||
|
// DUT instantiation
|
||||||
|
mux2_1 mux (
|
||||||
|
.S(ctrl),
|
||||||
|
.A(in_a),
|
||||||
|
.B(in_b),
|
||||||
|
.O(out)
|
||||||
|
);
|
||||||
|
|
||||||
|
// generate the clock
|
||||||
|
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",
|
||||||
|
$time, in_a, in_b, ctrl, out);
|
||||||
|
|
||||||
|
// Generate each input with a 20 ns delay between them
|
||||||
|
in_a = 1'b0;
|
||||||
|
in_b = 1'b0;
|
||||||
|
ctrl = 1'b0;
|
||||||
|
#20
|
||||||
|
if (out !== 0) $display("[FAILED] output should be 0");
|
||||||
|
in_a = 1'b1;
|
||||||
|
#20
|
||||||
|
if (out !== 1) $display("[FAILED] output should be 1");
|
||||||
|
ctrl = 1'b1;
|
||||||
|
in_a = 1'b0;
|
||||||
|
in_b = 1'b1;
|
||||||
|
#20
|
||||||
|
if (out !== 1) $display("[FAILED] output should be 1");
|
||||||
|
ctrl = 1'b0;
|
||||||
|
in_a = 1'b1;
|
||||||
|
#20
|
||||||
|
if (out !== 1) $display("[FAILED] output should be 1");
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule : tb_mux2_1
|
Loading…
Reference in New Issue