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
module xor_t(a, b, y);
mux2x1 u0(b, ~b, a, y);
endmodule
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
/*
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
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
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
~ : bitwise inversion
! : logical inversion
reg [3:0] a;
a = 4’b1010;
~a = 4’b0101;
!a = 0;
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
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
total number of processes: 6
at what time c, b, d => 0 time
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.
module top;
always @(a or b) begin
a <= b;
b <= a;
end
endmodule
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
`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
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