Digital Experiments
Digital Experiments
Source Code
`timescale 1ns/1ps
module counter(clk,rst,m,count);
input clk,rst,m;
output reg [3:0]count;
always@(posedge clk or negedge rst)
begin
if(!rst)
count=0;
if(m)
count=count+1;
else
count=count-1;
end
endmodule
Test-bench code
`timescale 1ns/1ps
module counter_test;
reg clk, rst,m;
wire [3:0] count;
Initial
begin
clk=0;
rst=0;#25;
Rst=1;
end
initial
begin
m=1;
#600 m=0;
rst=0;#25;
rst=1;
#500 m=0;
end
counter counter1(clk,m,rst, count);
always #5 clk=~clk;
initial
#1400 $finish;
endmodule
4-Bit Adder
Source Code – fa.v :-
module full_adder( A,B,CIN,S,COUT);
input A,B,CIN;
output S,COUT;
assign S = A^B^CIN;
assign COUT = (A&B) | (CIN&(A^B));
endmodule
Source Code – fa_4bit.v :-
module four_bit_adder(A,B,C0,S,C4);
input [3:0] A,[3:0] B,C0;
output [3:0] S,C4;
wire C1,C2,C3;
full_adder fa0 (A[0],B[0],C0,S[0],C1);
full_adder fa1 (A[1],B[1],C1,S[1],C2);
full_adder fa2 (A[2],B[2],C2,S[2],C3);
full_adder fa3 (A[3],B[3],C3,S[3],C4);
endmodule
Test Bench – fa_test.v :-
module test_4_bit;
reg [3:0] A;
reg [3:0] B;
reg C0;
wire [3:0] S;
wire C4;
four_bit_adder dut(A,B,C0,S,C4);
initial begin
A = 4'b0011;B=4'b0011;C0 = 1'b0; #10;
A = 4'b1011;B=4'b0111;C0 = 1'b1; #10;
A = 4'b1111;B=4'b1111;C0 = 1'b1; #10;
end
initial
#50 $finish;
endmodule
UART
Source Code – Transmitter :
// This code contains the UART Transmitter. This transmitter is able
// to transmit 8 bits of serial data, one start bit, one stop bit,
// and no parity bit. When transmit is complete o_Tx_done will be
// driven high for one clock cycle.
// Set Parameter CLKS_PER_BIT as follows:
// CLKS_PER_BIT = (Frequency of i_Clock)/(Frequency of UART)
// Example: 25 MHz Clock, 115200 baud UART
// (25000000)/(115200) = 217
module UART_TX
#(parameter CLKS_PER_BIT = 217)
(
input i_Clock,
input i_TX_DV,
input [7:0] i_TX_Byte,
output o_TX_Active,
output reg o_TX_Serial,
output o_TX_Done
);
parameter IDLE = 3'b000;
parameter TX_START_BIT = 3'b001;
parameter TX_DATA_BITS = 3'b010;
parameter TX_STOP_BIT = 3'b011;
parameter CLEANUP = 3'b100;
reg [2:0] r_SM_Main = 0;
reg [7:0] r_Clock_Count = 0;
reg [2:0] r_Bit_Index = 0;
reg [7:0] r_TX_Data = 0;
reg r_TX_Done = 0;
reg r_TX_Active = 0;
always @(posedge i_Clock)
begin
case (r_SM_Main)
IDLE :
begin
o_TX_Serial <= 1'b1; // Drive Line High for Idle
r_TX_Done <= 1'b0;
r_Clock_Count <= 0;
r_Bit_Index <= 0;
if (i_TX_DV == 1'b1)
begin
r_TX_Active <= 1'b1;
r_TX_Data <= i_TX_Byte;
r_SM_Main <= TX_START_BIT;
end
else
r_SM_Main <= IDLE;
end // case: IDLE
// Send out Start Bit. Start bit = 0
TX_START_BIT :
begin
o_TX_Serial <= 1'b0;
// Wait CLKS_PER_BIT-1 clock cycles for start bit to finish
if (r_Clock_Count < CLKS_PER_BIT-1)
begin
r_Clock_Count <= r_Clock_Count + 1;
r_SM_Main <= TX_START_BIT;
end
else
begin
r_Clock_Count <= 0;
r_SM_Main <= TX_DATA_BITS;
end
end // case: TX_START_BIT
// Wait CLKS_PER_BIT-1 clock cycles for data bits to finish
TX_DATA_BITS :
begin
o_TX_Serial <= r_TX_Data[r_Bit_Index];
if (r_Clock_Count < CLKS_PER_BIT-1)
begin
r_Clock_Count <= r_Clock_Count + 1;
r_SM_Main <= TX_DATA_BITS;
end
else
begin
r_Clock_Count <= 0;
// Check if we have sent out all bits
if (r_Bit_Index < 7)
begin
r_Bit_Index <= r_Bit_Index + 1;
r_SM_Main <= TX_DATA_BITS;
end
else
begin
r_Bit_Index <= 0;
r_SM_Main <= TX_STOP_BIT;
end
end
end // case: TX_DATA_BITS
// Send out Stop bit. Stop bit = 1
TX_STOP_BIT :
begin
o_TX_Serial <= 1'b1;
// Wait CLKS_PER_BIT-1 clock cycles for Stop bit to finish
if (r_Clock_Count < CLKS_PER_BIT-1)
begin
r_Clock_Count <= r_Clock_Count + 1;
r_SM_Main <= TX_STOP_BIT;
end
else
begin
r_TX_Done <= 1'b1;
r_Clock_Count <= 0;
r_SM_Main <= CLEANUP;
r_TX_Active <= 1'b0;
end
end // case: TX_STOP_BIT
// Stay here 1 clock
CLEANUP :
begin
r_TX_Done <= 1'b1;
r_SM_Main <= IDLE;
end
default :
r_SM_Main <= IDLE;
endcase
end
assign o_TX_Active = r_TX_Active;
assign o_TX_Done = r_TX_Done;
endmodule
Test bench :
// This testbench will exercise the UART RX.
// It sends out byte 0x37, and ensures the RX receives it correctly.
`timescale 1ns/10ps
`include "uart_tx.v"
`include "uart_rx.v"
module UART_TB ();
// Testbench uses a 25 MHz clock
// Want to interface to 115200 baud UART
// 25000000 / 115200 = 217 Clocks Per Bit.
parameter c_CLOCK_PERIOD_NS = 40;
parameter c_CLKS_PER_BIT = 217;
parameter c_BIT_PERIOD = 8600;
reg r_Clock = 0;
reg r_TX_DV = 0;
wire w_TX_Active, w_UART_Line;
wire w_TX_Serial;
reg [7:0] r_TX_Byte = 0;
wire [7:0] w_RX_Byte;
UART_RX #(.CLKS_PER_BIT(c_CLKS_PER_BIT)) UART_RX_Inst
(.i_Clock(r_Clock),
.i_RX_Serial(w_UART_Line),
.o_RX_DV(w_RX_DV),
.o_RX_Byte(w_RX_Byte)
);
UART_TX #(.CLKS_PER_BIT(c_CLKS_PER_BIT)) UART_TX_Inst
(.i_Clock(r_Clock),
.i_TX_DV(r_TX_DV),
.i_TX_Byte(r_TX_Byte),
.o_TX_Active(w_TX_Active),
.o_TX_Serial(w_TX_Serial),
.o_TX_Done()
);
// Keeps the UART Receive input high (default) when
// UART transmitter is not active
assign w_UART_Line = w_TX_Active ? w_TX_Serial : 1'b1;
always
#(c_CLOCK_PERIOD_NS/2) r_Clock <= !r_Clock;
34
// Main Testing:
initial
begin
// Tell UART to send a command (exercise TX)
@(posedge r_Clock);
@(posedge r_Clock);
r_TX_DV <= 1'b1;
r_TX_Byte <= 8'h3F;
@(posedge r_Clock);
r_TX_DV <= 1'b0;
end
endmodule
32-bit ALU
Test Bench :
module alu_32bit_tb_case;
reg [31:0]a;
reg [31:0]b;
reg [2:0]f;
wire [31:0]y;
alu_32bit_case test2(.y(y),.a(a),.b(b),.f(f));
initial
begin
a=32'h00000000;
b=32'hFFFFFFFF;
#10 f=3'b000;
#10 f=3'b001;
#10 f=3'b010;
#10 f=3'b100;
end
initial
#50 $finish;
endmodule
Test bench :
module alu_32bit_tb_if;
reg [31:0]a;
reg [31:0]b;
reg [2:0]f;
wire [31:0]y;
alu_32bit_if test(.y(y),.a(a),.b(b),.f(f));
initial
begin
a=32'h00000000;
b=32'hFFFFFFFF;
#10 f=3'b000;
#10 f=3'b001;
#10 f=3'b010;
#10 f=3'b100;
end
initial
#50 $finish;
endmodule
Source of JK Latch :
module jkff(J, K, en, Q);
input J, K, en;
output reg Q,Qm;
always @(en)
begin
if(J == 1 && K == 0)
Qm <= 1;
else if(J == 0 && K == 1)
Qm <= 0;
else if(J == 1 && K == 1)
Qm <= ~Qm;
end
endmodule