📄 alu.v
字号:
//Operations:
// 3'b100: C3 = A not B\
// 3'b101: C3 = A OR B | logic instructions
// 3'b110: C3 = A AND B/
// 3'b000: C3 = A << B \
// 3'b010: C3 = A >> B | shift
// 3'b001: C3 = A ASR B | instructions
// 3'b011: C3 = A + B \ arithmetic
// 3'b111: C3 = A - B | instructions
module alu (C3_BUS, A_BUS, B_BUS, ALU_OPCODE,CP, WORK_EX);
output [15:0] C3_BUS; // result bus
//output zero;
input [15:0] A_BUS, // operand bus A
B_BUS; // operand bus B
input [ 2:0] ALU_OPCODE; // opcode
input CP, // processor clock
WORK_EX; // work enable
reg [15:0] C3_BUS; // result
//reg zero;
wire [15:0] A_BUS, // operand bus A
B_BUS; // operand bus B
wire [ 2:0] ALU_OPCODE; // opcode
wire CP, // processor clock
WORK_EX; // work enable
reg [15:0] ALU_AREG, // operand register A
ALU_BREG; // operand register B
reg [ 2:0] ALU_OREG; // opcode register
wire [15:0] ARITH_RES, // result of ARITHMETIC
LOGIC_RES, // result of LOGIC
SHIFT_RES; // result of SHIFT
arithmetic ARITHMETIC (ARITH_RES, ALU_AREG, ALU_BREG, ALU_OREG);
logic LOGIC (LOGIC_RES, ALU_AREG, ALU_BREG, ALU_OREG);
shift SHIFT (SHIFT_RES, ALU_AREG, ALU_BREG[4:0], ALU_OREG);
// Read inputs with rising clock edge,
// if work enable
always @(posedge CP)
begin
if (WORK_EX)
begin
ALU_AREG = A_BUS;
ALU_BREG = B_BUS;
ALU_OREG = ALU_OPCODE;
//zero = (| LOGIC_RES ) || (| SHIFT_RES ) || (| ARITH_RES );
end
end
always @(ARITH_RES or LOGIC_RES or SHIFT_RES or ALU_OREG)
begin
casex(ALU_OREG[2:0])
3'b10x: C3_BUS = LOGIC_RES; // logic operations
3'b110: C3_BUS = LOGIC_RES; // logic operations
3'b00x: C3_BUS = SHIFT_RES; // shift operations
3'b010: C3_BUS = SHIFT_RES; // shift operations
3'bx11: C3_BUS = ARITH_RES; // arithmetic operations
endcase
end
endmodule
// arithmetic: execution of arithmetic operations
//
// Operations:
// 3'b011: RESULT = A_IN + B_IN
// 3'b111: RESULT = A_IN - B_IN
module arithmetic ( RESULT,A_IN, B_IN, OP_IN);
output [15:0] RESULT; // output result
input [15:0] A_IN, // input operand A
B_IN; // input operand B
input [2:0] OP_IN; // input opcode
reg [15:0] RESULT; // result
wire [15:0] A_IN, // operand A
B_IN; // operand B
wire [2:0] OP_IN; // opcode
reg [15:0] B_EFF; // operand B to be added effectively
always @(B_IN or OP_IN)
B_EFF = B_IN ^ {16{OP_IN[2]}};
always @(A_IN or B_EFF or OP_IN[2])
RESULT = A_IN + B_EFF + OP_IN[2];
endmodule // arithmetic
// logic: execution of logic operations
//
// Operations:
// 3'b101: RESULT = A AND B
// 3'b110: RESULT = A OR B
// 3'b100: RESULT = not B
//
//----------------------------------------------------------------------------
module logic (RESULT,A_IN, B_IN, OP_IN);
output [15:0] RESULT; // output result
input [15:0] A_IN, // input operand A
B_IN; // input operand B
input [ 2:0] OP_IN; // input opcode
reg [15:0] RESULT; // result
wire [15:0] A_IN, // operand A
B_IN; // operand B
wire [2:0] OP_IN; // opcode
//wire [15:0] result;
//assign result = RESULT;
//assign result = ~A_IN ;
always @(A_IN or B_IN or OP_IN)
begin
case(OP_IN)
3'b101: RESULT = A_IN & B_IN; // AND
3'b110: RESULT = A_IN | B_IN; // OR
endcase
end
endmodule // logic
//----------------------------------------------------------------------------
//
// shift: execute shift operations
//
// Operations:
// 3'b000: RESULT = A << B left shift
// 3'b010: RESULT = A >> B right shift
// 3'b001: RESULT = A ASR B right shift (sign maintaining)
module shift (RESULT,A_IN, B_IN, OP_IN);
output [15:0] RESULT; // output result
input [15:0] A_IN; // input operand A
input [ 4:0] B_IN; // input operand B
input [ 2:0] OP_IN; // input opcode
reg [15:0] RESULT; // result
reg [15:0] SIGN_mask;
wire [15:0] A_IN; // operand A
wire [ 4:0] B_IN; // operand B
wire [ 2:0] OP_IN; // opcode
always @ (A_IN or B_IN or OP_IN)
begin
if(OP_IN == 3'b000)
RESULT <= A_IN << B_IN;
else if(OP_IN == 3'b010)
RESULT <= A_IN >> B_IN;
else if(OP_IN == 3'b001)
begin
SIGN_mask <= ~({16{A_IN[15]}} >> B_IN);
RESULT <= SIGN_mask | A_IN;
end
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -