📄 3_04alu
字号:
//---------------------------------------------------------------------------- c0000
// c0001
// ALU: module of arithmetic logic unit c0002
// c0003
// Operations: c0004
// 4'b0000: C3 = A AND B \ c0005
// 4'b0001: C3 = A OR B | logic instructions c0006
// 4'b0010: C3 = A XOR B / c0007
// c0008
// 4'b0100: C3 = A << B \ c0009
// 4'b0101: C3 = A >> B | shift c0010
// 4'b0110: C3 = A ASR B | instructions c0011
// 4'b0111: C3 = A ROT B / c0012
// c0013
// 4'b1000: C3 = A + B \ c0014
// 4'b1001: C3 = A + B + C | arithmetic c0015
// 4'b1010: C3 = A - B | instructions c0016
// 4'b1011: C3 = A - B - C / c0017
// c0018
// Flags: c0019
// Bit 0 carry bit (1: carry) c0020
// Bit 1 overflow bit (1: overflow) c0021
// Bit 2 zero bit (1: result 0) c0022
// Bit 3 negative bit (1: result negative) c0023
// c0024
//---------------------------------------------------------------------------- c0025
c0026
module alu ( c0027
C3_BUS, FLAGS_FROM_ALU, c0028
A_BUS, B_BUS, ALU_CARRY, ALU_OPCODE, c0029
CP, WORK_EX c0030
); c0031
c0032
// Outputs c0033
output [31:0] C3_BUS; // result bus c0034
output [ 3:0] FLAGS_FROM_ALU; // result flags c0035
c0036
// Inputs c0037
input [31:0] A_BUS, // operand bus A c0038
B_BUS; // operand bus B c0039
input ALU_CARRY; // carry operand c0040
input [ 3:0] ALU_OPCODE; // opcode c0041
input CP, // processor clock c0042
WORK_EX; // work enable c0043
c0044
reg [31:0] C3_BUS; // result c0045
reg [ 3:0] FLAGS_FROM_ALU; // result flags c0046
wire [31:0] A_BUS, // operand bus A c0047
B_BUS; // operand bus B c0048
wire ALU_CARRY; // carry c0049
wire [ 3:0] ALU_OPCODE; // opcode c0050
wire CP, // processor clock c0051
WORK_EX; // work enable c0052
c0053
reg [31:0] ALU_AREG, // operand register A c0054
ALU_BREG; // operand register B c0055
reg [ 3:0] ALU_OREG; // opcode register c0056
reg ALU_CREG; // carry operand register c0057
wire [31:0] ARITH_RES, // result of ARITHMETIC c0058
LOGIC_RES, // result of LOGIC c0059
SHIFT_RES; // result of SHIFT c0060
wire ARITH_CFG, // carry result of ARITHMETIC c0061
SHIFT_CFG, // carry result of SHIFT c0062
ARITH_VFG; // overflow result of ARITHMETIC c0063
c0064
// c0065
// Instances c0066
// c0067
c0068
arithmetic ARITHMETIC ( c0069
ARITH_RES, ARITH_CFG, ARITH_VFG, c0070
ALU_AREG, ALU_BREG, ALU_CREG, ALU_OREG[1:0] c0071
); c0072
c0073
logic LOGIC (LOGIC_RES, ALU_AREG, ALU_BREG, ALU_OREG[1:0]); c0074
c0075
shift SHIFT (SHIFT_RES, SHIFT_CFG, ALU_AREG, ALU_BREG[4:0], ALU_OREG[1:0]); c0076
c0077
// c0078
// Read inputs with rising clock edge, c0079
// if work enable c0080
// c0081
always @(posedge CP) begin c0082
if (WORK_EX) begin c0083
fork c0084
ALU_AREG = #`DELTA A_BUS; c0085
ALU_BREG = #`DELTA B_BUS; c0086
ALU_OREG = #`DELTA ALU_OPCODE; c0087
ALU_CREG = #`DELTA ALU_CARRY; c0088
join c0089
end c0090
end c0091
c0092
// c0093
// Select result according to opcode; c0094
// update negative flag and zero flag c0095
// c0096
always @(ARITH_RES or LOGIC_RES or SHIFT_RES or ALU_OREG) begin c0097
case(ALU_OREG[3:2]) c0098
2'b00: C3_BUS = LOGIC_RES; // logic operations c0099
2'b01: C3_BUS = SHIFT_RES; // shift operations c0100
2'b10: C3_BUS = ARITH_RES; // arithmetic operations c0101
endcase c0102
FLAGS_FROM_ALU[3] = C3_BUS[31]; // negative flag c0103
FLAGS_FROM_ALU[2] = ~(|C3_BUS[31:0]); // zero flag c0104
end c0105
c0106
// c0107
// Update overflow flag c0108
// c0109
always @(ARITH_VFG) c0110
FLAGS_FROM_ALU[1] = ARITH_VFG; c0111
c0112
// c0113
// Select carry flag according to opcode c0114
// (logic operations do not generate a carry) c0115
// c0116
always @(ARITH_CFG or SHIFT_CFG or ALU_OREG) begin c0117
case(ALU_OREG[3]) c0118
2'b0: FLAGS_FROM_ALU[0] = SHIFT_CFG; // shift operations c0119
2'b1: FLAGS_FROM_ALU[0] = ARITH_CFG; // arithmetic operations c0120
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -