Lab 5

Download as pdf or txt
Download as pdf or txt
You are on page 1of 23

LAB-5

1. Write an RTL and testbench for 16x8 synchronous dual port


RAM memory.

module dualport_ram(input
clk,rst,rd_en,wr_en,input[7:0]data_in,[3:0]wr_addr,output
reg[7:0]data_out,input[3:0]rd_addr);
reg [7:0]mem[0:15];
integer i;
always@(posedge clk)
begin
if(rst)begin
for(i=0;i<16;i=i+1)begin
mem[i]=0;
end
end
else if(wr_en)begin
mem[wr_addr]<= data_in;
end
end
always @(posedge clk)
begin
if(rst)begin
data_out<= 'b0;
end
else if(rd_en)begin
data_out<= mem[rd_addr];
end
end
endmodule
//TESTBENCH

module dualport_RAM_tb;
reg clk,wr_en,data_in,wr_addr,rd_en,rd_addr;
reg [1:0]rst;
integer T;
initial
begin
clk=1'b0;
forever #(T/2)clk =~clk;
end
task reset;
begin
@(negedge clk)
rst=1'b1;
@(negedge clk)
rst=1'b0;
end
endtask
task write(input [7:0]i, input [3:0]j);
begin
wr_en=1'b1;
data_in=i;
wr_addr=j;
end
endtask
task read(input [3:0]k);
begin
@(negedge clk)
rd_en=1'b1;
rd_addr=k;
end
endtask
dualport_ram
DUT(.clk(clk),.wr_en(wr_en),.data_in(data_in),.wr_addr(wr_ad
dr),.rd_en(rd_en),.rd_addr(rd_addr));
initial
begin
reset;
write(8'd6,4'd3);
write(8'd5,4'd4);
write(8'd4,4'd3);
read(4'd4);
end
endmodule
2. Write an RTL and testbench for 8x16 asynchronous dual port
RAM memory.

module dp_async_ram #(parameter DEPTH = 8, WIDTH =


16,ADDR = 4)(
wr_clk,
rd_clk,
data_in,
data_out,
wr_addr,
rd_addr,
wr_en,
rd_en,
clr);
input [WIDTH-1:0] data_in;
output reg [WIDTH-1:0] data_out;
input wr_clk, rd_clk;
input clr;
input [ADDR-1:0] rd_addr, wr_addr;
input wr_en, rd_en;
integer i;
reg [WIDTH-1:0] mem[DEPTH-1:0];
always@(posedge wr_clk or posedge clr)
begin
if(clr)
begin
for(i = 0; i < DEPTH; i = i + 1)
mem[i] <= 0;
end
else if(wr_en)
begin
mem[wr_addr] <= data_in;
end
end
always@(posedge rd_clk or posedge clr)
begin
if(clr)
begin
data_out <= 0;
end
else if(rd_en)
begin
data_out<=mem[rd_addr];

end
end
endmodule

//TESTBENCH

module dualport_RAM_async_tb;
reg wr_clk,rd_clk,wr_en,data_in,wr_addr,rd_en,rd_addr;
reg [1:0]rst;
task reset;
begin
rst=1'b1;
end
endtask
task write(input [7:0]i, input [3:0]j);
begin
wr_clk=1'b1;
wr_en=1'b1;
data_in=i;
wr_addr=j;
end
endtask
task read(input [3:0]k);
begin
rd_clk=1'b1;
rd_en=1'b1;
rd_addr=k;
end
endtask
dp_async_ram
DUT(.wr_clk(wr_clk),.rd_clk(rd_clk),.wr_en(wr_en),.rd_en(rd_e
n),.wr_addr(wr_addr),.rd_addr(rd_addr),.data_in(data_in),.clr(r
st));
initial
begin
reset;
write(8'd6,3'd3);
write(8'd5,3'd2);
write(8'd4,3'd4);
read(3'd2);
end
endmodule
3. Write an RTL and testbench for clock buffer.

module clk_buf(clk);
input clk;
parameter tperiod=3;
time curr_time, last_time;
always @(posedge clk)
begin
curr_time = $time;
if((curr_time-last_time)>tperiod)
begin
$display("clock not periodic");
last_time = curr_time;
end
end
endmodule

//TESTBENCH

module clk_buf_tb;
reg Clock;
clk_buf dut(Clock);
task clk1;
begin
Clock = 1'b0;
#50 Clock = 1'b1;
#30 Clock = 1'b0;
#20 Clock = 1'b1;
#32 Clock = 1'b1;
#42 Clock = 1'b0;

end
endtask
task clk2;
begin
Clock=1'b0;
forever #10 Clock=~Clock;
end
endtask
initial
begin
clk1;
#100;
clk2;
#10;
end
endmodule
4. Write an RTL and testbench for 8x16 asynchronous single port
RAM memory.

module sp_8x16_ram (
input wr_en,
input en,
input [2:0] wr_addr,
input [15:0] data_in,
input rd_addr,
input rst,
output reg [15:0] data_out
);

reg [15:0] ram [0:7];


integer i;
always @*
begin : mem_write
if(rst)begin
for(i=0;i<8;i=i+1)begin
ram[i]=0;
end
end
else if (wr_en) begin
ram[wr_addr] <= data_in;
end
end
always @*
begin : mem_read
assign data_out = (en && !wr_en) ? ram[rd_addr] :1'bz;
end

endmodule
//TESTBENCH

module sp_8x16_ram_tb;
reg rst,wr_en,en,data_in,wr_addr,rd_addr;
task reset;
begin
rst=1'b1;
end
endtask
task write(input[15:0]i,input [2:0]j);
begin
wr_en=1'b1;
en=1'b0;
data_in=i;
wr_addr=j;
end
endtask
task read(input [2:0]k);
begin
en=1'b1;
rd_addr=k;
end
endtask
sp_8x16_ram
DUT(.rst(rst),.wr_en(wr_en),.en(en),.data_in(data_in),.wr_addr
(wr_addr),.rd_addr(rd_addr));
initial
begin
reset;
write(8'd4,3'd7);
write(8'd3,3'd6);
read(3'd7);
end endmodule
5. Write an RTL and testbench for 16x8 FIFO memory and verify
using testbench.

module fifo(input [7:0] data_in, input clk,rst,rd,wr, output


empty,full, output reg [3:0]fifo_cnt, output reg [7:0]data_out);
reg [7:0]fifo_ram[0:7];
reg [2:0]rd_ptr,wr_ptr;
assign empty = (fifo_cnt==0);
assign full=(fifo_cnt==8);
always @(posedge clk)
begin:write
if(wr && !full)
fifo_ram[wr_ptr] <= data_in;
else if(wr && rd)
fifo_ram[wr_ptr] <= data_in;
end

always @(posedge clk)


begin:read
if(rd && !empty)
data_out <= fifo_ram[rd_ptr];
else if(rd && wr)
data_out <= fifo_ram[rd_ptr];
end
always @(posedge clk)
begin:pointer
if(rst)begin
rd_ptr=0;
wr_ptr=0;
end
else if(rd && wr) begin
wr_ptr <= ((wr && !full)||(wr && rd))? wr_ptr+1: wr_ptr;
rd_ptr <= ((rd && !empty)||(wr && rd))? rd_ptr+1: rd_ptr;
end
end
always @(posedge clk)
begin:count
if(rst) fifo_cnt<=0;
else begin
case (wr|rd)
2'b00 : fifo_cnt <= fifo_cnt;
2'b01 : fifo_cnt <= (fifo_cnt==0)? 0 : fifo_cnt-1;
2'b10 : fifo_cnt <= (fifo_cnt==8)? 8 : fifo_cnt+1;
2'b11 : fifo_cnt <= fifo_cnt;
default : fifo_cnt <= fifo_cnt;
endcase
end
end
endmodule

//TESTBENCH

module fifo_tb;
reg clk;
reg [31:0] data_in;
reg rd;
reg wr;
reg rst;
wire [31:0] data_out;
wire empty;
wire full;
fifo DUT (

.clk(clk),

.data_in(data_in),

.rd(rd),

.wr(wr),

.data_out(data_out),

.rst(rst),

.empty(empty),

.full(full)

);

initial begin

clk = 1'b0;

data_in = 32'h0;

rd = 1'b0;

wr = 1'b0;

rst = 1'b1;
#100;
rst = 1'b1;
#20;
rst = 1'b0;
wr = 1'b1;
rd = 1'b1;
data_in = 32'h0;
#20;
data_in = 32'h1;
#20;
data_in = 32'h2;
#20;
data_in = 32'h3;
#20;
data_in = 32'h4;
#20;
wr = 1'b1;
rd = 1'b1;
end
always #10 clk = ~clk;
endmodule

You might also like