|
- /* 设计思路 */
- //分成两个模块来设计:control_decoder(即控制信号产生模块),根据相应的条件产生控制信号ALU_control
- // ALU_out(即运算模块),根据产生的控制信号来进行相应的运算,需要在模块里面调用control_decoder模块(即例化),
- // 将control_decoder模块产生的控制信号送到ALU_out模块,将两个模块连起来。这样在写Testbench的时候只需要调用例化ALU_out模块即可
- // 也可以不再ALU_out模块里面调用control_decoder模块,在写Testbench的时候将两个模块都例化,在用到ALU整体的时候把两个模块都调用(即例化)
- `timescale 1ns/100ps
- module control_decoder(ALU_op,Func,ALU_control);
- input wire [1:0] ALU_op;
- input wire [5:0] Func;
- reg [2:0] ALU_control_reg; //中间变量
- output wire [2:0] ALU_control; //输出控制信号
-
- parameter Add = 3'b010,Subtract = 3'b110,And = 3'b000,Or = 3'b001,SLT = 3'b111;
- parameter S0 = 6'b100_000,S1 = 6'b100_010,S2 = 6'b100_100,S3 = 6'b100_101,S4 = 6'b101_010;
- parameter s0 = 2'b00,s1 = 2'b01,s2 = 2'b10;
-
- always @(ALU_op or Func)
- begin
- case(ALU_op)
- s0:
- ALU_control_reg <= Add;
- s1:
- ALU_control_reg <= Subtract;
- s2:
- begin
- case(Func)
- S0:
- ALU_control_reg <= Add;
- S1:
- ALU_control_reg <= Subtract;
- S2:
- ALU_control_reg <= And;
- S3:
- ALU_control_reg <= Or;
- S4:
- ALU_control_reg <= SLT;
- endcase
- end
- endcase
- end
-
- assign ALU_control = ALU_control_reg;
-
- endmodule
- `timescale 1ns/100ps
- module ALU_out(A,B,ALU_op_out,Func_in,Y,Zero);
- input wire [31:0] A;
- input wire [31:0] B;
-
- input [1:0] ALU_op_out; //这两个信号必须在端口声明里面进行定义,作为这个模块的输入
- input [5:0] Func_in;
-
- reg[31:0] Y_reg;//中间变量
-
- output wire [31:0] Y; //ALU输出信号
- output wire Zero; //零值信号
-
- wire [1:0] ALU_op_out;
- wire [5:0] Func_in;
- wire [2:0] ALU_control_out;
-
- parameter s0 = 3'b000,s1 = 3'b010,s2= 3'b110,s3 = 3'b001,s4 = 3'b111;
- // 与 加 减 或 SLT
- control_decoder control_decoder_out(.ALU_op(ALU_op_out),.Func(Func_in),.ALU_control(ALU_control_out));
-
- always @(A or B or ALU_control_out) //这里的敏感条件必须把ALU_control_out加上,否则最后输出会有问题!!!!!!!!!!!
- begin
- case(ALU_control_out)
- s0:
- Y_reg <= A&B;
- s1:
- Y_reg <= A+B;
- s2:
- Y_reg <= A-B;
- s3:
- Y_reg <= A|B;
- s4:
- Y_reg <= A<B ? 32'b1 : 32'b0; //SLT
- endcase
- end
-
- assign Y = Y_reg;
- assign Zero = (A==B);
- endmodule
- `timescale 1ns/100ps
- module ALU_out_tb();
- reg [31:0] A_tb,B_tb;
- reg [1:0] ALU_op_tb;
- reg [5:0] Func_tb;
-
- wire [31:0] Y_tb;
- wire Zero_tb;
-
- ALU_out ALU_tb(.A(A_tb),.B(B_tb),.ALU_op_out(ALU_op_tb),.Func_in(Func_tb),.Y(Y_tb),.Zero(Zero_tb));
-
- initial
- begin
- A_tb <= 9;
- B_tb <= 1;
- ALU_op_tb <= 2'b00; //加 10 1010
- Func_tb <= 6'b100000;
- #2;
-
- A_tb <= 9;
- B_tb <= 1;
- ALU_op_tb <= 2'b01; //减 8 1000
- Func_tb <= 6'b100000;
- #2;
-
- A_tb <= 9;
- B_tb <= 1;
- ALU_op_tb <= 2'b10; //加 10 1010
- Func_tb <= 6'b100000;
- #2;
-
- A_tb <= 9;
- B_tb <= 1;
- ALU_op_tb <= 2'b10; //减 8 1000
- Func_tb <= 6'b100010;
- #2;
-
- A_tb <= 9;
- B_tb <= 1;
- ALU_op_tb <= 2'b10; //与 1 0001
- Func_tb <= 6'b100100;
- #2;
-
- A_tb <= 9;
- B_tb <= 1;
- ALU_op_tb <= 2'b10; //或 9 1001
- Func_tb <= 6'b100101;
- #2;
-
- A_tb <= 9;
- B_tb <= 1;
- ALU_op_tb <= 2'b10; //SLT 0 0000
- Func_tb <= 6'b101010;
- #2;
-
- #100 $stop; //使仿真停止,若没有死循环的话这句话可加可不加
- end
-
- endmodule
复制代码 |
|