Welcome, guest! Login / Register - Why register?
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&#40;"TestVars.vcd"&#41;;
     $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

Your Name: Code Language: