module add_4(
input [3:0] X, Y,
output [3:0] sum,
output Cout
);
assign {Cout, sum} = X+Y;
endmodule
module mult_4(
input [3:0] X, Y,
output [7:0] Prod
);
assign Prod = X*Y;
endmodule
// Two operants calculation
// 00 Adder
// 01 Mul
// 10 Comp
// 11 Mux
module Comb_Logic_param
#(parameter Dwidth=4)(
input [Dwidth-1:0] X, Y,
input [1:0] Inst,
input Sel,
output reg [Dwidth-1:0] sum, Sel_out,
output reg Cout, XEGY,
output reg [2*Dwidth-1:0] Prod
);
localparam Add = 2'b00;
localparam Mul = 2'b01;
localparam Comp = 2'b10;
localparam Mux = 2'b11;
always @(*)begin
case (Inst)
// Full Adder
// Si = Xi*Ci_b + Yi*Ci_b + Ci-1*Ci_b + Xi*Yi*Ci-1
// Ci = Xi*Yi + Yi*Ci-1 + Xi*Ci-1
Add: {Cout, sum} <= X+Y;
// Mult
Mul: Prod <= X*Y;
// Comparator
Comp:
begin
if (X >= Y) XEGY <= 1'b1;
else XEGY <= 1'b0;
end
Mux:
if (Sel == 1'b1) Sel_out <= X;
else Sel_out <= Y;
endcase
end
endmodule
`timescale 1ns/100ps
module Comb_Logic_param_tb;
reg [4-1:0] X, Y;
reg [1:0] Inst;
reg Sel;
wire [4-1:0] sum;
wire Cout, XEGY, Sel_out;
wire [2*4-1:0] Prod;
Comb_Logic_param
#(
.Dwidth(4)
)
U1(
.X(X),
.Y(Y),
.Inst(Inst),
.Sel(Sel),
.sum(sum),
.Cout(Cout),
.XEGY(XEGY),
.Sel_out(Sel_out),
.Prod(Prod)
);
initial
begin
X = 4'b0101;
Y = 4'b0010;
Sel = 1'b1;
Inst = 2'b00;
#5 Inst = 2'b01;
#5 Inst = 2'b10;
#5 Inst = 2'b11;
#5 X = 4'b0011;
#5 Y = 4'b1100;
#5 Sel = 1'b0;
#5 Inst = 2'b00;
#5 Inst = 2'b01;
#5 Inst = 2'b10;
#5 Inst = 2'b11;
#10 $finish;
end
endmodule
可以看出结果随着指令在改变。
`define PLUS 3'd0
`define MINUS 3'd1
`define BAND 3'd2
`define BOR 3'd3
`define BINV 3'd4
module alu(
output reg [7:0] out,
input [2:0] opcode,
input [7:0] a,b
);
always @(opcode, a, b) begin
case(opcode)
`PLUS: out = a+b;
`MINUS: out = a-b;
`BAND: out = a&b;
`BOR: out = a|b;
`BINV: out = ~out;
default: out = 8'hx;
endcase
end
endmodule
`timescale 1ns/100ps
module alu_tb;
reg [7:0] a,b;
reg [2:0] opcode;
wire [7:0] out;
localparam times=5;
alu U1(
.out(out),
.opcode(opcode),
.a(a),
.b(b)
);
initial begin
a = {$random}%256;
b = {$random}%256;
opcode=3'd0;
repeat(times) begin
#100 a = {$random}%256;
b = {$random}%256;
opcode = opcode+1;
end
#100 $finish;
end
endmodule