16 bit ALU Verilog design

[code title=”sep_alu.v Main module” collapse=”true”]
//B Turley
//16 bit ALU

timescale 1ns/100ps

module sep_alu(Y, cout16, cout15, rightout, leftout, A, B, s, cin, rightin, leftin);
output [15:0] Y;
output cout16, cout15;
output rightout, leftout;
input [15:0] A; //first input
input [15:0] B; //second input
input [3:0] s; //operation input
input cin; // carry in
input rightin, leftin; // shift inputs

wire [15:0] cvect;
wire [15:0] rvect;
wire [15:0] lvect;

alu_slice u0(Y[0], cvect[0], rvect[0], lvect[0], A[0], B[0], s, cin, rvect[1], leftin);
alu_slice u1(Y[1], cvect[1], rvect[1], lvect[1], A[1], B[1], s, cvect[0], rvect[2], lvect[0]);
alu_slice u2(Y[2], cvect[2], rvect[2], lvect[2], A[2], B[2], s, cvect[1], rvect[3], lvect[1]);
alu_slice u3(Y[3], cvect[3], rvect[3], lvect[3], A[3], B[3], s, cvect[2], rvect[4], lvect[2]);
alu_slice u4(Y[4], cvect[4], rvect[4], lvect[4], A[4], B[4], s, cvect[3], rvect[5], lvect[3]);
alu_slice u5(Y[5], cvect[5], rvect[5], lvect[5], A[5], B[5], s, cvect[4], rvect[6], lvect[4]);
alu_slice u6(Y[6], cvect[6], rvect[6], lvect[6], A[6], B[6], s, cvect[5], rvect[7], lvect[5]);
alu_slice u7(Y[7], cvect[7], rvect[7], lvect[7], A[7], B[7], s, cvect[6], rvect[8], lvect[6]);
alu_slice u8(Y[8], cvect[8], rvect[8], lvect[8], A[8], B[8], s, cvect[7], rvect[9], lvect[7]);
alu_slice u9(Y[9], cvect[9], rvect[9], lvect[9], A[9], B[9], s, cvect[8], rvect[10], lvect[8]);
alu_slice u10(Y[10], cvect[10], rvect[10], lvect[10], A[10], B[10], s, cvect[9], rvect[11], lvect[9]);
alu_slice u11(Y[11], cvect[11], rvect[11], lvect[11], A[11], B[11], s, cvect[10], rvect[12], lvect[10]);
alu_slice u12(Y[12], cvect[12], rvect[12], lvect[12], A[12], B[12], s, cvect[11], rvect[13], lvect[11]);
alu_slice u13(Y[13], cvect[13], rvect[13], lvect[13], A[13], B[13], s, cvect[12], rvect[14], lvect[12]);
alu_slice u14(Y[14], cvect[14], rvect[14], lvect[14], A[14], B[14], s, cvect[13], rvect[15], lvect[13]);
alu_slice u15(Y[15], cvect[15], rvect[15], lvect[15], A[15], B[15], s, cvect[14], rightin, lvect[14]);

assign cout16 = cvect[15];
assign cout15 = cvect[14];
assign rightout = rvect[0];
assign leftout = lvect[15];


[code title="sep_alu_tb.v Testbench" collapse="true"]

File: sep_alu_tb.v
Author: Jeremy Wood
Date: 6-8-04

Desc: This is the test bench for the ALU

modified 9-18-04 Added driveable left and right
shift inputs
modified 2-17-11 By B K Turley,
Corrected error with cin timing

timescale 1ns/100ps

module sep_alu_tb;

reg [15:0] A; // A Input
reg [15:0] B; // B Input
reg [3:0] s; // Operation select input
reg cin; // Carry input
reg rightIn; // Right Input from the shift operations
reg leftIn; // Left Input from the shift operations

wire [15:0] Y; // Y Ouput
wire cout16, cout15; // Carry Outputs
wire rightout, leftout; // Shift Outputs

// Invoke an instance of the test bench
sep_alu alu(Y, cout16, cout15, rightout, leftout, A, B, s, cin, rightIn, leftIn);

initial begin

$dumpvars(6, sep_alu_tb);

A <= 16’habcd;
B <= 16’h1234;
rightIn <= 1’b0;
leftIn <= 1’b0;

// Addition
#20 s <= 4’b0000;
cin <= 1’b0;

// Addition with Carry
#20 cin <= 1’b1;

// Subtract with Borrow
#20 s <= 4’b0001;
cin <= 1’b0;

// Subtraction
#20 cin <= 1’b1;

// Transfer A
#20 s <= 4’b0010;
cin <= 1’b0;

// Increment
#20 cin <=1’b1;

// Decrement A
#20 s <= 4’b0011;
cin <= 1’b0;

// Transfer A
#20 s <= 4’b0010;

// AND
#20 s <= 4’b0100;

// OR
#20 s <= 4’b0101;

// XOR
#20 s <= 4’b0110;

// Complement A
#20 s <= 4’b0111;

// Shift right A into F
#20 s <= 4’b1000;

// Shift left A into F
#20 s <= 4’b1100;

// 42 + -13
#20 A <= 16’d42;
B <= 16’b1111111111110011;
s <= 4’d0;

// -42 – -13
#20 A <= 16’b1111111111010110;
B <= 16’b1111111111110011;
s <= 4’d1;

// 70 + 80
#20 A <= 16’d70;
B <= 16’d80;
s <= 4’d0;

// -70 + -80
#20 A <= 16’b1111111110111010;
B <= 16’b1111111110110000;

// Clear signals for Simvision
#20 A <= 16’h0000;
B <= 16’h0000;

#20 $finish;

[code title=”alu_slice.v module” collapse=”true”]
//B Turley
//ALU one bit slice

timescale 1ns/100ps

module alu_slice(Y, cout, rightout, leftout, A, B, s, cin, rightin, leftin);
output Y;
output cout;
output rightout, leftout;
input A;
input B;
input [3:0] s;
input cin;
input rightin, leftin;

wire sum;
wire Bin, Lout;

mux_4to1 arithmatic(Bin, s[1:0], B, ~B, 1'b0, 1'b1);
mux_4to1 logicpart(Lout, s[1:0], A&B, A|B, A^B, ~A);
adder_1bit adder(sum, cout, A, Bin, cin);
mux_4to1 slicemux(Y, s[3:2], sum, Lout, rightin, leftin);

assign rightout = A;
assign leftout = A;


[code title="adder_1bit.v module" collapse="true"]
// 1 bit adder
// BK Turley

timescale 1ns/100ps

module adder_1bit(sum, cout, in1, in2, cin);

input in1;
input in2;
input cin;

output sum;
output cout;

assign cout = (in1 & in2) | (in1 & cin) | (in2 & cin);
assign sum = in1 ^ in2 ^ cin;


[code title=”mux_4to1.v module” collapse=”true”][/code]
// 4 channel, 1 bit mux
// BK Turley

`timescale 1ns/100ps

module mux_4to1(out, sel, in0, in1, in2, in3);

output out;
input [1:0] sel;
input in0;
input in1;
input in2;
input in3;

reg out;

always @( sel or in0 or in1 or in2 or in3)

case (sel)
2’b00 : out <= in0;
2’b01 : out <= in1;
2’b10 : out <= in2;
2’b11 : out <= in3;
default : out <= in0;


Leave a Reply

Your email address will not be published. Required fields are marked *