1. Implement 4×1 mux using continuous assignments
    a. Implement 8×1 mux using 4×1 mux implemented above

module mux4x1(i0, i1, i2, i3, sel, y); //1.5 marks
input i0, i1, i2, i3;
input [1:0] sel;
output y;
assign y = (sel == 2’b00) ? i0 : (sel == 2’b01) ? i1 : (sel == 2’b10) ? i2 : (sel == 2’b11) ? i3 : 1’bx;
endmodule

a. Implement 8×1 mux using 4×1 mux implemented above

module mux8x1(i0, i1, i2, i3, i4, i5, i6, i7, sel, y);
input i0, i1, i2, i3, …i7;
input [2:0] sel;
output y;

mux4x1 u0(i0, i1, i2, i3, sel[1:0], n1);
mux4x1 u1(i4, i5, i6, i7, sel[1:0], n2);
mux4x1 u2(n1, n2, 0, 0, {1’b0, sel[2]}, y);

endmodule

  1. Implement XOR gate using 2×1 Mux
    XOR =
    Truth table:
    a b y
    0 1 1
    0 0 0
    1 0 1
    1 1 0

module xor_t(a, b, y);

mux2x1 u0(b, ~b, a, y);
endmodule

  1. Below vector assignment, show the individual vector bit position copies.
    a. Reg [3:-2] a;
    b. Reg [7:2] b;
    c. a = b

a[-2] = b[2];
a[-1] = b[3];
a[0] = b[4];
a[1] = b[5];
a[2] = b[6];
a[3] = b[7];
//4. Implement Verilog code for synchronous reset DFF with active low reset

module dff(clk, rst, d, q);
input clk, rst, d;
output reg q;

always @(posedge clk) begin
if (rst == 0) begin
q = 0;
end
else begin
q = d;
end
end
endmodule
/*

  1. Implement 3 bit ring counter using logic gates and FF’s
    a. Hint: Use Truth table and K-maps

100 -> 010 -> 001

Truth table
C2 C1 C0 N2 N1 N0
0 0 0 1 0 0
0 0 1 1 0 0
0 1 0 0 0 1
0 1 1 1 0 0
1 0 0 0 1 0
1 0 1 1 0 0
1 1 0 1 0 0
1 1 1 1 0 0

N2:
N2 = C0 + ~C2~C1 + C2C1 = C0 + C2 XNOR C1
N1 = C2~C1~C0
N0 = ~C2C1~C0
*/
`include “Q4.v”
module ring_counter(clk, rst, count);
input clk, rst;
output [2:0] count;

xnor g1(p1, count[2], count[1]);
or g2 (n2, p1, count[0]);
and g3(n1, count[2], ~count[1], ~count[0]);
and g4(n0, ~count[2], count[1], ~count[0]);
dff g5(clk, rst, n2, count[2]);
dff g6(clk, rst, n1, count[1]);
dff g7(clk, rst, n0, count[0]);
endmodule

module tb;
reg clk, rst;
wire [2:0] count;

ring_counter dut(clk, rst, count);

initial begin
clk = 0;
forever #5 clk = ~clk;
end

initial begin
rst = 0;
#20;
rst = 1;
#500;
$finish;
end

endmodule

  1. Write logic to check the frequency of a clock matching the frequency number defined as a parameter

module top;
reg clk;
parameter FREQ = 100; //MHZ
realtime prev_edge_time, cur_edge_time;
real tp, freq;

always @(posedge clk) begin
prev_edge_time = cur_edge_time;
cur_edge_time = $time;
tp = cur_edge_time – prev_edge_time;
freq = 1/tp;
if (freq != FREQ) begin
$display(“freq not matching the parameter value”);
end
end
endmodule

  1. Write a task for below requirements
    a. Task used for both write and read to the memory
    i. wr_rd_f used to decide write or read
    b. Task with arguments
    i. Start location from where to access the memory
    ii. Number of locations to access
    c. Assume memory of WIDTH and DEPTH parameters

task write_read_mem(input reg wr_rd_f, input reg [ADDR_WIDTH-1:0] addr, input reg [DEPTH-1:0] num_locations);
begin
for (i = 0; i < num_locations; i=i+1) begin
@(posedge clk);
addr_i = addr + i;
if (wr_rd_f == 1) wdata_i = $random; //mem[i];
wr_rd_i = wr_rd_f;
valid_i = 1;
wait (ready_o == 1);
@(posedge clk);
addr_i = 0;
wdata_i = 0;
wr_rd_i = 0;
valid_i = 0;
end
end
endtask

  1. Illustrate difference between ~ and ! operators

~ : bitwise inversion
! : logical inversion

reg [3:0] a;
a = 4’b1010;
~a = 4’b0101;
!a = 0;

  1. Implement 4×1 mux only using conditional operator
    assign y = (sel == 2’b00) ? i0 : (sel == 2’b01) ? i1 : (sel == 2’b10) ? i2 : (sel == 2’b11) ? i3 : 1’bx;
    module mem_ctrl(p1,p2,p3,p4,p5,q1,q2,q3,q4,q5,q6);
    input p1,p2,p3,p4,p5;
    output q1,q2,q3,q4,q5,q6; //wire or reg?
    wire n1,n2,n3,n4,n5,n6;

addr_gen addr_gen_i(.i1(p1), .i2(p2), .i3(n3), .o1(q1), .o2(n1), .o3(n2));
data_gen data_gen_i(.i1(p3), .i2(p4), .o1(n3), .o2(q6), .o3(n4));
timing_ctrl timing_ctrl_i(.i1(n1), .i2(n2), .i3(n4), .i4(p5), .o1(q2), .o2(q4), .o3(q3), .o4(q5));

endmodule

  1. Write Verilog for below circuit

module top(a, b, clk, rst, z);
input a, b, clk, rst;
output z;

dff g0(clk, rst, a, n1);
and g1(n2, n1, b);
dff g2(clk, rst, n2, y);
not g3(n3, y);
dff g4(clk, rst, n3, z);

//another solution
always @(posedge clk) begin
if (rst == 1) begin
n1 <= 0;
y <= 0;
z <= 0;
end
else begin
n1 <= a;
y <= n2;
z <= n3;
end
end

always @(*) begin
n1 = n1 & b;
n3 = ~y;
end
endmodule

  1. How many processes are in below code? at what time c, b, and d assignment will happen?
    a. initial begin
    b. fork
    c. #5; c = 1;
    d. #5; b = 0;
    e. #5; d = c;
    f. join
    g. End

total number of processes: 6
at what time c, b, d => 0 time

  1. Use an example to explain the difference between casex and casez
    a = 2’b1x;
    casex (a) //will match with all 1 green marked below
    2’b00 : begin
    End
    2’b10 : begin
    End
    2’b11 : begin
    End
    2’b1x : begin
    End
    2’b1z : begin
    end
    endcase
  2. Proper Timescale declaration is required for clock frequency generation. Explain this using an example.
    Ex: 30 Mhz

module top;
real freq;
real tp;

initial begin
freq= 30;
tp = 1000/freq; //MHz -> ns conversion
clk = 0;
forever #(tp/2) clk = ~clk;
end
endmodule
ABove code will fail with default time scale in the tool
default timescale : 1ns/1ns (time precision: 1ns)
tp = 1000/30 = 33.33 ns
tp/2 = 16.666 ns
default timescale = time precision (1ns) = 16.666 ns rounded off to 17ns

clock generated will be off : 34ns TP => which is not 30MHz

how to fix this:
`timescale 1ns/1ps
tp will not be rounded off.

  1. Write a Verilog code to interchange two integer values without using temporary variable.

module top;
always @(a or b) begin
a <= b;
b <= a;
end
endmodule

  1. Explain what is Synthesis?
    a. List down 10 synthesizable Verilog constructs
    b. List down 10 non-synthesizable Verilog constructs

synthesis:
– process of converting RTL or bheavioral code in to gate level netlist

10 synthesizable cosntructs:
always, assign, and, or, function, if, operators, case, task(with no delays), genvar, parameter

10 non-synthesizable cosntructs:
initial, fork, repeat, while, #, real, time, forever, table, display

  1. Write a synthesizable Verilog code below traffic light controller (6 marks)
    a. Red time: 20 sec
    b. Yellow time: 10 sec
    c. Green time: 40 sec
    d. Clock frequency: 10Khz

`timescale 1s/1ms
module tlc(clk, rst, state, paddr, pwdata, pwrite, penable, pready);
parameter RED_TIME=30; //30sec/10ns = 310*9
parameter GREEN_TIME=60;
parameter YELLOW_TIME=10;
parameter RED=2’b00;
parameter GREEN=2’b01;
parameter YELLOW=2’b10;

input clk, rst;
output reg [1:0] state;
reg [1:0] next_state;
integer count;

reg [7:0] red_time_reg; //0
reg [7:0] yellow_time_reg; //4
reg [7:0] green_time_reg; //8
reg [7:0] mode_reg; //8 : [2:0] = 3’b000 => normal traffic, 001 => high traffic
always @(posedge clk) begin
if (rst == 1) begin
count = 0;
state = RED;
next_state = RED;
end
else begin
case (state)
RED : begin
//repeat(20) @(posedge clk) => non-synthesizable
count = count + 1;
if (count == 20) begin
next_state = GREEN;
count = 0;
end
end
GREEN : begin
count = count + 1;
if (count == 40) begin
next_state = YELLOW;
count = 0;
end
end
YELLOW : begin
count = count + 1;
if (count == 10) begin
next_state = RED;
count = 0;
end
end
endcase
end
end

endmodule

  1. Implement Verilog code of non-blocking SIPO (10 marks)
  2. Write Verilog code for 5 bit Dynamic pattern detector (6 marks)

module pattern_det(clk, rst, d_in, valid_in, pattern_detected);
input clk, rst, d_in, valid_in;
output reg pattern_detected;
reg [4:0] pattern_to_detect; //what is the pattern I want to detect
reg [4:0] pattern_collected;
reg [5:0] next_state;

always @(posedge clk) begin
if (rst == 1) begin
next_state = S_RESET;
pattern_detected = 0;
pattern_collected = 0;
pattern_to_detect = 5’b00001; //BBBBC
end
else begin
pattern_detected = 0;
pattern_collected = pattern_collected << 1; //Left shift whole pattern by 1 bit
pattern_collected[0] = d_in;
if (pattern_collected[4:0] == pattern_to_detect[4:0]) begin
pattern_detected = 1;
end
end
end
endmodule

Course Registration