Psst.. new poll here.
Psst.. new forums here.
Microsoft is blocking us again (TY IP Reputation!) so just use oauth login instead. :)
Paste
Pasted as Verilog by nya ( 17 years ago )
//Example MINI-ALU
`timescale 10ns/1ns
`define DELAY 1
module ClockGen( output reg clk );
initial begin
clk = 0;
end
always begin
#`DELAY clk = ~clk;
end
endmodule
`define WORD_WIDTH 8
`define CTRL_WIDTH 4
`define CTRL_NOP 0
`define CTRL_AND 1
`define CTRL_OR 2
`define CTRL_XOR 3
`define CTRL_ADD 4
`define CTRL_SUB 5
module example(
input wire clk,
input wire [ `CTRL_WIDTH-1:0 ] control,
input wire [ `WORD_WIDTH-1:0 ] InA,
input wire [ `WORD_WIDTH-1:0 ] InB,
output reg [ `WORD_WIDTH-1:0 ] AluOut
);
//Variable to store result of ALU operation
reg [ `WORD_WIDTH-1:0 ] AluResult;
//In any cast pass AluResult to AluOut by clock, so ALU becomes synchronous
always @( posedge clk ) AluOut <= AluResult;
//Status flags
reg CarryFlag;
reg ZeroFlag;
//Alu inputs, made 1 bit wider, for carry sake. MSB is initialized with 0.
wire [ (`WORD_WIDTH-1)+1:0 ] WideInA;
assign WideInA = {1'b0, InA};
wire [ (`WORD_WIDTH-1)+1:0 ] WideInB;
assign WideInB = {1'b0, InB};
//Divide wide sum to carry component and value component for Add and Sub, similarily.
wire AddCarry;
wire [ `WORD_WIDTH-1:0 ] AddAB;
assign {AddCarry, AddAB} = WideInA + WideInB;
wire SubCarry;
wire [ `WORD_WIDTH-1:0 ] SubAB;
assign {SubCarry, SubAB} = WideInA - WideInB;
//Process Zero flag
always @( AluResult ) begin
if (AluResult == 0) ZeroFlag <= 1'b1;
else ZeroFlag <= 1'b0;
end
//Process data
always @( posedge clk ) begin
//Perform alu operation
case ( control )
//Simple logic operations
`CTRL_AND: AluResult = InA & InB;
`CTRL_OR: AluResult = InA | InB;
`CTRL_XOR: AluResult = InA ^ InB;
//operations which can set carry (arithmetic)
`CTRL_ADD: begin
AluResult = AddAB;
CarryFlag <= AddCarry;
end
`CTRL_SUB: begin
AluResult = SubAB;
CarryFlag <= SubCarry;
end
//Nop and others bypass data forward
`CTRL_NOP: AluResult = InA;
default: AluResult = InA;
endcase
end
endmodule
module TestBench();
wire clk;
reg [ `CTRL_WIDTH-1:0 ] control;
reg [ `WORD_WIDTH-1:0 ] a;
reg [ `WORD_WIDTH-1:0 ] b;
wire [ `WORD_WIDTH-1:0 ] out;
ClockGen clock( clk );
example test( clk, control, a, b, out );
initial begin
$dumpfile("TestVars.vcd");
$dumpvars;
//Test add 0,0
a <= 8'd0;
b <= 8'd0;
control <= `CTRL_ADD;
#2
//Test sub 100,110
a <= 8'd100;
b <= 8'd110;
control <= `CTRL_SUB;
#2
//Test NOP
a <= 8'd0;
b <= 8'd0;
control <= `CTRL_NOP;
#2
#4 $finish();
end
endmodule
Revise this Paste