OpenCores
URL https://opencores.org/ocsvn/quark/quark/trunk

Subversion Repositories quark

[/] [quark/] [trunk/] [01_SysRequirements/] [03_InternalRequirements/] [02_VerilogAlgorithmDesign/] [alu_8bit.v] - Rev 3

Go to most recent revision | Compare with Previous | Blame | View Log

`timescale 1ns / 1ps
 
module ALU_8bit(
    clk,
	 rst,
	 en,
	 ready,
	 opcode,
	 reg_in_1,
	 reg_in_2,
	 reg_out,
	 reg_bank
    );
 
	 input wire clk;
	 input wire rst;
	 input wire en;
	 input wire [7:0] opcode;
	 input wire [7:0] reg_in_1;
	 input wire [7:0] reg_in_2;
 
	 output reg ready;
	 output reg [7:0] reg_out;
 
	 /* ALU flags steps registers
		N
		Set when the result of the operation was Negative.
		Z
		Set when the result of the operation was Zero.
		C
		Set when the operation resulted in a Carry.
		V
		Set when the operation caused oVerflow.
 
		A carry occurs if the result of an add, subtract, or compare is greater than or equal to 232, or as the result of an inline barrel shifter operation in a move or logical instruction.
		Overflow occurs if the result of an add, subtract, or compare is greater than or equal to 231, or less than -231.
	 */
    `define N 0:0
    `define Z 1:1
    `define C 2:2
    `define V 3:3
    output reg [3:0] reg_bank;
 
    reg [15:0] reg_out_temp;
 
	/* ROL and ROR steps and registers */
	`define R_FIRST_STEP  1'b0
	`define R_SECOND_STEP 1'b1
    reg rotation_step;
 
	/* math steps  and registers */
	`define M_FIRST_STEP  2'b00
	`define M_SECOND_STEP 2'b01
	`define M_THIRD_STEP  2'b10
	reg [1:0] math_step;
    reg [7:0] dividend;
    reg [7:0] denom;
    reg [7:0] current;
    reg [7:0] temp_result;
 
    always@(posedge clk) begin
        if (rst == 1'b1) begin
            reg_out_temp <= 16'b0000;
            reg_out <= 8'h00;
            ready <= 1'b0;
            rotation_step <= `R_FIRST_STEP;
            reg_bank <= 4'b0000;
            math_step <= `M_FIRST_STEP;
            current <= 8'h01;
            temp_result <= 8'h00;
            dividend <= 8'h00;
            denom <= 8'h00;
        end else if (en == 1'b1) begin
            ready <= 1'b0;
 
            case(opcode)
                8'h00:begin /* SUM(reg_out) reg_in_1,reg_in_2 [reg_out = reg_in_1 + reg_in_2]*/
                    reg_out <= reg_in_1 + reg_in_2;
                    ready <= 1'b1;
                end
 
                8'h01:begin /* SUB(reg_out) reg_in_1,reg_in_2 [reg_out = reg_in_1 - reg_in_2]*/
                    reg_out <= reg_in_1 - reg_in_2;
 
                    if (reg_in_2 > reg_in_1) begin
                        ready <= 1'b1;
                    end
 
                    if (reg_in_2 == reg_in_1) begin
                        ready <= 1'b1;
                    end
 
                    ready <= 1'b1;
                end
 
                8'h02:begin /* MUL(reg_out) reg_in_1,reg_in_2 [reg_out = reg_in_1 * reg_in_2]*/
 
                end
 
                8'h03:begin /* DIV(reg_out) reg_in_1,reg_in_2 [reg_out = reg_in_1 / reg_in_2]*/
                    case(math_step)
                        `M_FIRST_STEP:begin
                            dividend <= reg_in_1;
                            denom <= reg_in_2;
                            math_step <= `M_SECOND_STEP;
                        end
 
                        `M_SECOND_STEP:begin /* shift left to find first bit with value 1 */
                            if (denom <= dividend) begin
                                denom <= denom << 1;
                                current <= current << 1;
                            end else begin
                                denom <= denom >> 1; /* shift right reg_in_2 to align it with reg_in_1 */
                                current <= current >> 1;
                                math_step <= `M_THIRD_STEP;
                            end
                        end
 
                        `M_THIRD_STEP:begin 
                            if (current != 0) begin
                                if (dividend >= denom) begin
                                    dividend <= dividend - denom;
                                    temp_result <= temp_result | current;
                                end
 
                                denom <= denom >> 1;
                                current <= current >> 1;
                            end else begin
                                reg_out <= temp_result;
								current <= 8'h01;
                                temp_result <= 8'h00;
                                math_step <= `M_FIRST_STEP;
                                ready <= 1'b1;
                            end
                        end
                    endcase
                end
 
                8'h04:begin /* MOD(reg_out) reg_in_1,reg_in_2 [reg_out = reg_in_1 % reg_in_2]*/
 
                end
 
                8'h05:begin /* AND(reg_out) reg_in_1,reg_in_2 [reg_out = reg_in_1 & reg_in_2]*/
                    reg_out <= reg_in_1 & reg_in_2;
                    ready <= 1'b1;
                end
 
                8'h06:begin /* OR(reg_out) reg_in_1,reg_in_2 [reg_out = reg_in_1 | reg_in_2]*/
                    reg_out <= reg_in_1 | reg_in_2;
                    ready <= 1'b1;
                end
 
                8'h07:begin /* NOT(reg_out) reg_in_1 [reg_out = ~reg_in_1]*/
                    reg_out <= ~reg_in_1;
                    ready <= 1'b1;
                end
 
                8'h08:begin /* XOR(reg_out) reg_in_1,reg_in_2 [reg_out = reg_in_1 ^ reg_in_2]*/
                    reg_out <= reg_in_1 ^ reg_in_2;
                    ready <= 1'b1;
                end
 
                8'h09:begin /* SHL(reg_out) reg_in_1,reg_in_2 [reg_out = reg_in_1 << reg_in_2]*/
                    reg_out <= reg_in_1 << reg_in_2;
                    ready <= 1'b1;
                end
 
                8'h0A:begin /* SHR(reg_out) reg_in_1,reg_in_2 [reg_out = reg_in_1 >> reg_in_2]*/
                    reg_out <= reg_in_1 >> reg_in_2;
                    ready <= 1'b1;ready <= 1'b1;
                end
 
                8'h0B:begin /* ROL(reg_out) reg_in_1,reg_in_2 [reg_out = ??]*/
                    if (rotation_step == `R_FIRST_STEP) begin
                        reg_out_temp <= reg_in_1 << (reg_in_2 & 8'h07);
                        rotation_step <= `R_SECOND_STEP;
                    end else begin
                        reg_out <= reg_out_temp[15:8] | reg_out_temp[7:0];
                        ready <= 1'b1;
                        rotation_step <= `R_FIRST_STEP;
                    end
                end
 
                8'h0C:begin /* ROR(reg_out) reg_in_1,reg_in_2 [reg_out = ??]*/
                    if (rotation_step == `R_FIRST_STEP) begin
                        reg_out_temp <= {reg_in_1[7:0],8'b00} >> (reg_in_2 & 8'h07);
                        rotation_step <= `R_SECOND_STEP;
                    end else begin
                        reg_out <= reg_out_temp[15:8] | reg_out_temp[7:0];
                        ready <= 1'b1;
                        rotation_step <= `R_FIRST_STEP;
                    end
                end
            endcase
        end
    end
endmodule
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.