This is Sue Jang

Building a processor (2) - ALU control 본문

Engineering courses/Digital System Design

Building a processor (2) - ALU control

Suyun 2023. 10. 26. 06:36

Design Sources

// top module

module reg_alu(
    input CLK,
    input [15:0] SW,
    input [4:0] BTNS,
    output [7:0] CA,AN,
    output reg [15:0] LED=0
    );
wire zero,neg,sclk;
wire [15:0] write_data,rega_data,regb_data;   

 
registers r_array (.CLK(CLK),.rega_addr(SW[11:8]),.regb_addr(SW[7:4]),.write_addr(SW[3:0]),
                   .write_data(write_data),.write_enable(1),.rega_data(rega_data),
                   .regb_data(regb_data));
                                 
ALU alu_unit ( .a(rega_data) ,.b(regb_data), .alu_control(SW[14:12]),
                         .result(write_data),.zero(zero),.neg(neg));     
                                                         
ssegx8 display ( .CLK(CLK), .VALUE({rega_data,regb_data}),.SSEG_CA(CA),.SSEG_AN(AN));   
 
always @(posedge CLK)
    begin
        LED<=write_data;
    end                 
endmodule
module registers(
    input CLK,
    input [3:0] rega_addr,regb_addr,write_addr,
    input [15:0] write_data,
    input write_enable,
    output reg [15:0] rega_data=0,regb_data=0
    );
    reg [15:0] reg_array [15:0];
    reg state=0;
    reg [4:0] i;
initial
    begin
        for (i=0;i<16;i=i+1)
            reg_array[i]=i;
    end        
    
always @(posedge CLK)   
    begin
        case (state)
        0:begin
            rega_data<=reg_array[rega_addr];
            regb_data<=reg_array[regb_addr];
            state<=1;
          end 
        1: begin
            if (write_enable==1)
                reg_array[write_addr]<=write_data;
            state<=0; 
           end     
        endcase
    end
endmodule
`timescale 1ns / 1ps
module ALU(
 input  [15:0] a,  //src1
 input  [15:0] b,  //src2
 input  [2:0] alu_control, //function sel
 
 output reg [15:0] result,  //result 
 output zero,neg
    );

always @(*)
begin 
 case(alu_control)
 3'b000: result = a + b; // add
 3'b001: result = a - b; // sub
 3'b010: result = a^b;
 3'b011: result = a<<b;
 3'b100: result = a>>b;
 3'b101: result = a & b; // and
 3'b110: result = a | b; // or
 3'b111: result = a;   //sub 
 default:result = a + b; // add
 endcase
end
assign zero = (result==16'd0); 
assign neg = result[15];
endmodule
`timescale 1ns / 1ps
module ssegx8(
    input CLK,
    input [31:0] VALUE,
    output reg [7:0] SSEG_CA,
    output reg [7:0] SSEG_AN
    );
reg [20:0] digit_counter;
reg [3:0] digits;
always @(posedge CLK)
begin
	digit_counter<=digit_counter+1;
	case (digits)
				    // pgfedcba
		0:SSEG_CA = 8'b11000000;
		1:SSEG_CA = 8'b11111001;
		2:SSEG_CA = 8'b10100100; 
		3:SSEG_CA = 8'b10110000;
		4:SSEG_CA = 8'b10011001; 
		5:SSEG_CA = 8'b10010010; 
		6:SSEG_CA = 8'b10000010; 
		7:SSEG_CA = 8'b11111000; 
		8:SSEG_CA = 8'b10000000;
		9:SSEG_CA = 8'b10010000;
		10:SSEG_CA=~8'b11110111; 
		11:SSEG_CA=~8'b11111100; 
		12:SSEG_CA=~8'b10111001; 
		13:SSEG_CA=~8'b11011110; 
		14:SSEG_CA=~8'b11111001; 
		15:SSEG_CA=~8'b11110001; 
		
	 endcase
 
	case (digit_counter[16:14])
		
		0 : begin
				SSEG_AN=8'b01111111;
				digits<=VALUE[31:28];
			end
		1 : begin
				SSEG_AN=8'b10111111;
				digits<=VALUE[27:24];
			end
		2 : begin
				SSEG_AN=8'b11011111;
				digits<=VALUE[23:20];
			end
		3 : begin
				SSEG_AN=8'b11101111;

				digits<=VALUE[19:16];
			end		
        4 : begin
                SSEG_AN=8'b11110111;
                digits<=VALUE[15:12];
            end
        5 : begin
                SSEG_AN=8'b11111011;
                digits<=VALUE[11:8];
            end
        6 : begin
                SSEG_AN=8'b11111101;
                digits<=VALUE[7:4];
            end
        7 : begin
                SSEG_AN=8'b11111110;
                digits<=VALUE[3:0];
            end        		
	endcase	

end
endmodule