RISC-V base implementation #1
							
								
								
									
										22
									
								
								rtl/alu.v
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								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 | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| module instruction (input [31:0] address, | module instruction (input  [31:0] address, | ||||||
|                        output [31:0] instruction); |                     output [31:0] instruction); | ||||||
|      |      | ||||||
|     reg [31:0] memory [63:0]; |     reg [31:0] memory [63:0]; | ||||||
|  |  | ||||||
| @@ -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"; |  | ||||||
							
								
								
									
										10
									
								
								rtl/memory.v
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								rtl/memory.v
									
									
									
									
									
								
							| @@ -1,8 +1,8 @@ | |||||||
| module memory (input clock, reset, | module memory (input         clock, reset, | ||||||
|                     input we, |                input         we, | ||||||
|                     input [31:0] address, |                input  [31:0] address, | ||||||
|                     input [31:0] data_in, |                input  [31:0] data_in, | ||||||
|                     output [31:0] data_out); |                output [31:0] data_out); | ||||||
|      |      | ||||||
|     reg [63:0] memory [31:0]; |     reg [63:0] memory [31:0]; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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,6 +1,6 @@ | |||||||
| module program_counter (input clock, reset, | module program_counter (input             clock, reset, | ||||||
|            input [31:0] pc_new_addr, |                         input      [31:0] pc_new_addr, | ||||||
|            output reg [31:0] pc_addr); |                         output reg [31:0] pc_addr); | ||||||
|      |      | ||||||
|     always @ (posedge clock, posedge reset) begin |     always @ (posedge clock, posedge reset) begin | ||||||
|         if (reset == 1'b1) |         if (reset == 1'b1) | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| module registers_bank (input clock, reset, we, | module registers_bank (input         clock, reset, we, | ||||||
|                        input [4:0] sel_in, sel_out_a, sel_out_b, |                        input  [4:0]  sel_in, sel_out_a, sel_out_b, | ||||||
|                        input [31:0] data_in, |                        input  [31:0] data_in, | ||||||
|                        output [31:0] data_out_a, data_out_b); |                        output [31:0] data_out_a, data_out_b); | ||||||
|      |      | ||||||
|     reg [31:0] registers[31:0]; |     reg [31:0] registers[31:0]; | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
							
								
								
									
										61
									
								
								tb/tb_alu.v
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								tb/tb_alu.v
									
									
									
									
									
								
							| @@ -1,41 +1,36 @@ | |||||||
| `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 |         $monitor("time=%3d, in_a=%d, in_b=%d, ctrl=%b, q=%d \n", | ||||||
|     // Use the monitor task to display the FPGA IO |                     $time, in_a, in_b, op_code, out); | ||||||
|     $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_a = 1'b0; |         in_b = 1'b0; | ||||||
|     in_b = 1'b0; |         op_code = 3'b000; | ||||||
|     op_code = 3'b000; |         #20 | ||||||
|     #20 |         if (out !== 0) $display("[FAILED] output should be 0"); | ||||||
|     if (out !== 0) $display("[FAILED] output should be 0"); |         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"); |         in_b = 1'b1; | ||||||
|     in_b = 1'b1; |         #20 | ||||||
|     #20 |         if (out !== 2) $display("[FAILED] output should be 2"); | ||||||
|     if (out !== 2) $display("[FAILED] output should be 2"); |         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,61 +1,39 @@ | |||||||
| `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; |         .S(ctrl), | ||||||
| reg [31:0] in_b; |         .A(in_a), | ||||||
| reg ctrl; |         .B(in_b), | ||||||
| wire [31:0] out; |         .O(out) | ||||||
|  |     ); | ||||||
|  |  | ||||||
| // DUT instantiation |     initial begin | ||||||
| mux2_1 mux ( |         $monitor("time=%3d, in_a=%d, in_b=%d, ctrl=%b, q=%d \n", | ||||||
|     .S(ctrl), |                     $time, in_a, in_b, ctrl, out); | ||||||
|     .A(in_a), |  | ||||||
|     .B(in_b), |  | ||||||
|     .O(out) |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| // generate the clock |         in_a = 1'b0; | ||||||
| initial begin |         in_b = 1'b0; | ||||||
|     clk = 1'b0; |         ctrl = 1'b0; | ||||||
|     // forever #1 clk = ~clk; |         #20 | ||||||
| end |         if (out !== 0) $display("[FAILED] output should be 0"); | ||||||
|  |         in_a = 1'b1; | ||||||
| // Generate the reset |         #20 | ||||||
| initial begin |         if (out !== 1) $display("[FAILED] output should be 1"); | ||||||
|     reset = 1'b1; |         ctrl = 1'b1; | ||||||
|     #10 |         in_a = 1'b0; | ||||||
|     reset = 1'b0; |         in_b = 1'b1; | ||||||
| end |         #20 | ||||||
|  |         if (out !== 1) $display("[FAILED] output should be 1"); | ||||||
| // Test stimulus |         ctrl = 1'b0; | ||||||
| initial begin |         in_a = 1'b1; | ||||||
|     // Use the monitor task to display the FPGA IO |         #20 | ||||||
|     $monitor("time=%3d, in_a=%d, in_b=%d, ctrl=%b, q=%d \n", |         if (out !== 1) $display("[FAILED] output should be 1"); | ||||||
|                 $time, in_a, in_b, ctrl, out); |     end | ||||||
|  |  | ||||||
|     // 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 | 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; |         .clock(clk), | ||||||
| reg reset; |         .reset(reset), | ||||||
|  |         .out(out) | ||||||
|  |     ); | ||||||
|  |  | ||||||
| // Design Inputs and outputs |     initial begin | ||||||
| wire [31:0] out; |         reset = 1'b1; | ||||||
|  |         #10 | ||||||
| // DUT instantiation |         reset = 1'b0; | ||||||
| risc_v_cpu risc_v_cpu ( |     end | ||||||
|     .clock(clk), |  | ||||||
|     .reset(reset), |     initial begin | ||||||
|     .out(out) |         clk = 1'b0; | ||||||
| ); |         for (i = 0; i < 100; i = i + 1) begin | ||||||
|  |             #1 clk = ~clk; | ||||||
| // Generate the reset |         end | ||||||
| initial begin |  | ||||||
|     reset = 1'b1; |  | ||||||
|     #10 |  | ||||||
|     reset = 1'b0; |  | ||||||
| end |  | ||||||
|  |  | ||||||
|  |  | ||||||
| // generate the clock |  | ||||||
| initial begin |  | ||||||
|     clk = 1'b0; |  | ||||||
|     for (i = 0; i < 100; i = i + 1) begin |  | ||||||
|         #1 clk = ~clk; |  | ||||||
|     end |     end | ||||||
| end |  | ||||||
|  |  | ||||||
| endmodule : tb_risc_v_cpu | endmodule : tb_risc_v_cpu | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user