VLSI LAB DIGITAL DESIGN PROGRAMS
ALU
module alu_32bit_case(y,a,b,f);
input [31:0]a;
input [31:0]b;
input [2:0]f;
output reg [31:0]y;
always@(*)
begin
case(f)
3'b000:y=a&b;//AND Operation
3'b001:y=a|b;//OR Operation
3'b010:y=~(a&b);//NAND Operation
3'b011:y=~(a|b);//NOR Operation
3'b100:y=~b; // not opeartion
3'b101:y=a+b;//Addition
3'b110:y=a-b;//Subtraction
3'b111:y=a*b;//Multiply
default:y=32'bx;
endcase
end
endmodule
TEST BENCH CODE-ALU
module alu_32bit_tb_case;
reg [31:0]a;
reg [31:0]b;
reg [2:0]f;
wire [31:0]y;
alu_32bit_case dut(y,a,b,f);
initial
begin
a=32'h00000000;
b=32'hFFFFFFFF;
#10 f=3'b000;
#10 f=3'b001;
#10 f=3'b010;
#10 f=3'b011;
#10 f=3'b100;
#10 f=3'b101;
#10 f=3'b110;
#10 f=3'b111;
end
initial
#500 $finish;
Endmodule
JK-FF
module JK_FF (JK, clock, q, qb);
input [1:0] JK;
input clock;
output reg q, qb;
always @ (posedge clock)
begin
case (JK)
2'b00 : q = q;
2'b01 : q = 1'b0;
2'b10 : q = 1'b1;
2'b11 : q =~ q;
endcase
qb =~ q;
end
endmodule
TESTBENCH-JK FF
module JK_ff_tb;
reg [1:0] JK;
reg clock;
wire q, qb;
JK_FF uut(JK, clock, q, qb);
initial
clock=1'b1;
always #5 clock=~clock;
initial
begin
JK=2'b00; #20;
JK=2'b01; #20;
JK=2'b10; #20;
JK=2'b11; #50;
end
initial
$monitor ($time, "JK=%b q=%b qb=%b ", JK, q, qb);
Endmodule
D-FF
module DFF( Q,Qb,D,clock,reset);
output reg Q;
output Qb;
input D,clock,reset;
always @(posedge clock)
begin
if (reset == 1'b1) //If at reset
Q <= 1'b0;
else
Q <= D;
end
assign Qb = ~Q;
endmodule
D FF TEST BENCH CODE
module dff_tb;
reg clock, reset, D;
wire Q, Qb;
DFF dut (Q, Qb, D, clock, reset);
initial
begin
clock=1'b1;
reset=1'b0;
end
always #5 clock=~clock;
always #80 reset=~reset;
initial
begin
#10 D =1'b1;
#10 D =1'b0;
#10 D =1'b1;
#10 D =1'b0;
end
initial
#100 $finish;
endmodule
UART
`timescale 1 ns / 1 ps
module uart (
reset ,
txclk ,
ld_tx_data ,
tx_data ,
tx_enable ,
tx_out ,
tx_empty ,
rxclk ,
uld_rx_data ,
rx_data ,
rx_enable ,
rx_in ,
rx_empty
);
// Port declarations
input reset ;
input txclk ;
input ld_tx_data ;
input [7:0] tx_data ;
input tx_enable ;
output tx_out ;
output tx_empty ;
input rxclk ;
input uld_rx_data ;
output [7:0] rx_data ;
input rx_enable ;
input rx_in ;
output rx_empty ;
// Internal Variables
reg [7:0] tx_reg ;
reg tx_empty ;
reg tx_over_run ;
reg [3:0] tx_cnt ;
reg tx_out ;
reg [7:0] rx_reg ;
reg [7:0] rx_data ;
reg [3:0] rx_sample_cnt ;
reg [3:0] rx_cnt ;
reg rx_frame_err ;
reg rx_over_run ;
reg rx_empty ;
reg rx_d1 ;
reg rx_d2 ;
reg rx_busy ;
// UART RX Logic
always @ (posedge rxclk or posedge reset)
if (reset) begin
rx_reg <= 0;
rx_data <= 0;
rx_sample_cnt <= 0;
rx_cnt <= 0;
rx_frame_err <= 0;
rx_over_run <= 0;
rx_empty <= 1;
rx_d1 <= 1;
rx_d2 <= 1;
rx_busy <= 0;
end else begin
// Synchronize the asynch signal
rx_d1 <= rx_in;
rx_d2 <= rx_d1;
// Uload the rx data
if (uld_rx_data) begin
rx_data <= rx_reg;
rx_empty <= 1;
end
// Receive data only when rx is enabled
if (rx_enable) begin
// Check if just received start of frame
if ( ! rx_busy && ! rx_d2) begin
rx_busy <= 1;
rx_sample_cnt <= 1;
rx_cnt <= 0;
end
// Start of frame detected, Proceed with rest of data
if (rx_busy) begin
rx_sample_cnt <= rx_sample_cnt + 1;
// Logic to sample at middle of data
if (rx_sample_cnt == 7) begin
if ((rx_d2 == 1) && (rx_cnt == 0)) begin
rx_busy <= 0;
end else begin
rx_cnt <= rx_cnt + 1;
// Start storing the rx data
if (rx_cnt > 0 && rx_cnt < 9) begin
rx_reg[rx_cnt - 1] <= rx_d2;
end
if (rx_cnt == 9) begin
rx_busy <= 0;
// Check if End of frame received correctly
if (rx_d2 == 0) begin
rx_frame_err <= 1;
end else begin
rx_empty <= 0;
rx_frame_err <= 0;
// Check if last rx data was not unloaded,
rx_over_run <= (rx_empty) ? 0 : 1;
end
end
end
end
end
end
if ( ! rx_enable) begin
rx_busy <= 0;
end
end
// UART TX Logic
always @ (posedge txclk or posedge reset)
if (reset) begin
tx_reg <= 0;
tx_empty <= 1;
tx_over_run <= 0;
tx_out <= 1;
tx_cnt <= 0;
end else begin
if (ld_tx_data) begin
if ( ! tx_empty) begin
tx_over_run <= 0;
end else begin
tx_reg <= tx_data;
tx_empty <= 0;
end
end
if (tx_enable && ! tx_empty) begin
tx_cnt <= tx_cnt + 1;
if (tx_cnt == 0) begin
tx_out <= 0;
end
if (tx_cnt > 0 && tx_cnt < 9) begin
tx_out <= tx_reg[tx_cnt -1];
end
if (tx_cnt == 9) begin
tx_out <= 1;
tx_cnt <= 0;
tx_empty <= 1;
end
end
if ( ! tx_enable) begin
tx_cnt <= 0;
end
end
endmodule
UART-TEST BENCH
`timescale 1 ns / 1 ps
module uart_tb;
// Inputs
reg reset;
reg txclk;
reg ld_tx_data;
reg [7:0] tx_data;
reg tx_enable;
reg rxclk;
reg uld_rx_data;
reg rx_enable;
reg rx_in;
// Outputs
wire tx_out;
wire tx_empty;
wire [7:0] rx_data;
wire rx_empty;
// uncomment lines for convenient access to internal var
//wire [7:0] rx_reg = uut.rx_reg;
//wire [3:0] rx_cnt = uut.rx_cnt;
//wire [3:0] rx_sample_cnt = uut.rx_sample_cnt;
//wire rx_d2 = uut.rx_d2;
//wire rx_busy = uut.rx_busy;
// Instantiate the Unit Under Test (UUT)
uart uut (
.reset(reset),
.txclk(txclk),
.ld_tx_data(ld_tx_data),
.tx_data(tx_data),
.tx_enable(tx_enable),
.tx_out(tx_out),
.tx_empty(tx_empty),
.rxclk(rxclk),
.uld_rx_data(uld_rx_data),
.rx_data(rx_data),
.rx_enable(rx_enable),
.rx_in(rx_in),
.rx_empty(rx_empty)
);
//generate a master clk
reg clk;
//setup clocks
initial clk=0;
always #10 clk = ~clk; //this speed is somewhat arbitrary for the purposes of this sim...clk
should be 16X faster than desired baud rate. I like my simulation time to match the physical
system.
//generate rxclk and txclk so that txclk is 16 times slower than rxclk
reg [3:0] counter;
initial begin
rxclk=0;
txclk=0;
counter=0;
end
always @(posedge clk) begin
counter<=counter+1;
if (counter == 15) txclk <= ~txclk;
rxclk<= ~rxclk;
end
//setup loopback
// always @ (tx_out) rx_in=tx_out;
initial begin
// Initialize Inputs
reset = 1;
ld_tx_data = 0;
tx_data = 0;
tx_enable = 1;
uld_rx_data = 0;
rx_enable = 1;
` rx_in = 1;
// Wait 100 ns for global reset to finish
#500;
reset = 0;
// Add stimulus here
// Send data using tx portion of UART and wait until data is recieved
tx_data=8'b0111_1111;
#1200 tx_data=8'b0000_1111;
#1200 tx_data=8'b1111_0000;
wait (tx_empty==1); //make sure data can be sent
ld_tx_data = 1; //load data to send
wait (tx_empty==0); //wait until data loaded for send
$display("Data loaded for send");
ld_tx_data = 0;
wait (tx_empty==1); //wait for flag of data to finish sending
$display("Data sent");
wait (rx_empty==0); //wait for
$display("RX Byte Ready");
uld_rx_data = 1;
wait (rx_empty==1);
$display("RX Byte Unloaded: %b",rx_data);
#100;
$stop;
end
endmodule
4BIT-COUNTER
Verilog code for 4-Bit Up-Down Counter:
//Defining a Timescale for Precision
`timescale 1ns/1ps
//Defining Module
module counter(clk,rst,m,count);
//Defining Inputs and Outputs (4bit)
input clk,rst,m;
output reg [3:0]count;
//The Block is executed when EITHER of positive edge of clock
//Both are independent events or Neg Edge of Rst arrives
always@(posedge clk or negedge rst)
begin
if(!rst)
count=0;
if(m)
count=count+1;
else
count=count-1;
end
endmodule
4BIT COUNTER-TEST BENCH
Test-bench code for 4-Bit Up-Down Counter:
`timescale 1ns/1ps // Creating Time Scale as in Source Code
module counter_test; // Defining Module Name without Port List
reg clk, rst,m; // Defining I/P as Registers [to Hold Values]
wire [3:0] count; // Defining O/P as Wires [To Probe Waveforms]
Initial
begin
clk=0; // Initializing Clock and Reset
rst=0;#25; // All O/P is 4’b0000 from t=0 to t=25ns.
Rst=1; // Up-Down counting is allowed at posedge clk
end
initial
begin
m=1; // Condition for Up-Count
#600 m=0; // Condition for Down-Count
rst=0;#25;
rst=1;
#500 m=0;
end
counter counter1(clk,m,rst, count); // Instantiation of Source Code
always #5 clk=~clk; // Inverting Clk every 5ns
initial
#1400 $finish; // Finishing Simulation at t=1400ns
endmodule