Skip to content

Commit

Permalink
Add Repo Files
Browse files Browse the repository at this point in the history
  • Loading branch information
MohamedHussein27 committed Oct 5, 2024
1 parent 548599f commit c566669
Show file tree
Hide file tree
Showing 11 changed files with 629 additions and 0 deletions.
Binary file added Doc/Synchronous FIFO Verification.pdf
Binary file not shown.
70 changes: 70 additions & 0 deletions RTL/FIFO.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
////////////////////////////////////////////////////////////////////////////////
// Author: Kareem Waseem
// Course: Digital Verification using SV & UVM
//
// Description: FIFO Design
//
////////////////////////////////////////////////////////////////////////////////
module FIFO(data_in, wr_en, rd_en, clk, rst_n, full, empty, almostfull, almostempty, wr_ack, overflow, underflow, data_out);
parameter FIFO_WIDTH = 16;
parameter FIFO_DEPTH = 8;
input [FIFO_WIDTH-1:0] data_in;
input clk, rst_n, wr_en, rd_en;
output reg [FIFO_WIDTH-1:0] data_out;
output reg wr_ack, overflow;
output full, empty, almostfull, almostempty, underflow;

localparam max_fifo_addr = $clog2(FIFO_DEPTH);

reg [FIFO_WIDTH-1:0] mem [FIFO_DEPTH-1:0];

reg [max_fifo_addr-1:0] wr_ptr, rd_ptr;
reg [max_fifo_addr:0] count;

always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
wr_ptr <= 0;
end
else if (wr_en && count < FIFO_DEPTH) begin
mem[wr_ptr] <= data_in;
wr_ack <= 1;
wr_ptr <= wr_ptr + 1;
end
else begin
wr_ack <= 0;
if (full & wr_en)
overflow <= 1;
else
overflow <= 0;
end
end

always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
rd_ptr <= 0;
end
else if (rd_en && count != 0) begin
data_out <= mem[rd_ptr];
rd_ptr <= rd_ptr + 1;
end
end

always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
count <= 0;
end
else begin
if ( ({wr_en, rd_en} == 2'b10) && !full)
count <= count + 1;
else if ( ({wr_en, rd_en} == 2'b01) && !empty)
count <= count - 1;
end
end

assign full = (count == FIFO_DEPTH)? 1 : 0;
assign empty = (count == 0)? 1 : 0;
assign underflow = (empty && rd_en)? 1 : 0;
assign almostfull = (count == FIFO_DEPTH-2)? 1 : 0;
assign almostempty = (count == 1)? 1 : 0;

endmodule
201 changes: 201 additions & 0 deletions SV Based Verification/FIFO.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
////////////////////////////////////////////////////////////////////////////////
// Author: Kareem Waseem
// Course: Digital Verification using SV & UVM
//
// Description: FIFO Design
//
////////////////////////////////////////////////////////////////////////////////
module FIFO(fifo_if.DUT fifoif);
parameter FIFO_WIDTH = 16;
parameter FIFO_DEPTH = 8;
logic clk;
logic [FIFO_WIDTH-1:0] data_in;
logic rst_n, wr_en, rd_en;
logic [FIFO_WIDTH-1:0] data_out;
logic wr_ack, overflow;
logic full, empty, almostfull, almostempty, underflow;

// assigning signals to be interfaced
// inputs
assign clk = fifoif.clk;
assign data_in = fifoif.data_in;
assign rst_n = fifoif.rst_n;
assign wr_en = fifoif.wr_en;
assign rd_en = fifoif.rd_en;
// outputs
assign fifoif.data_out = data_out;
assign fifoif.wr_ack = wr_ack;
assign fifoif.overflow = overflow;
assign fifoif.full = full;
assign fifoif.empty = empty;
assign fifoif.almostfull = almostfull;
assign fifoif.almostempty = almostempty;
assign fifoif.underflow = underflow;



localparam max_fifo_addr = $clog2(FIFO_DEPTH);

reg [FIFO_WIDTH-1:0] mem [FIFO_DEPTH-1:0];

reg [max_fifo_addr-1:0] wr_ptr, rd_ptr;
reg [max_fifo_addr:0] count;

// properties
// immediate signals
always_comb begin
if(!rst_n) begin
`ifdef SIM
count_aa: assert final(count == 0);
wr_ptr_aa: assert final(wr_ptr == 0);
rd_ptr_aa: assert final(rd_ptr == 0);
full_aa: assert final(full == 0);
empty_aa: assert final(empty == 1);
underflow_aa: assert final(underflow == 0);
almostfull_aa: assert final(almostfull == 0);
almostempty_aa: assert final(almostempty == 0);
wr_ack_aa: assert final(wr_ack == 0);
overflow_aa: assert final(overflow == 0);
`endif
end
if((count == FIFO_DEPTH))
`ifdef SIM
full_a: assert final(full == 1);
`endif
if((count == 0))
`ifdef SIM
empty_a: assert final(empty == 1);
`endif
if((count == FIFO_DEPTH - 1))
`ifdef SIM
almostfull_a: assert final(almostfull == 1);
`endif
if((count == 1))
`ifdef SIM
almostempty_a: assert final(almostempty == 1);
`endif
end
// output flags
property ack_p;
@(posedge clk) disable iff (rst_n == 0) wr_en && (count < FIFO_DEPTH) |=> wr_ack ;
endproperty

property overflow_p;
@(posedge clk) disable iff (rst_n == 0) ((count == FIFO_DEPTH) && wr_en) |=> (overflow == 1);
endproperty

property underflow_p;
@(posedge clk) disable iff (rst_n == 0) (empty) && (rd_en) |=> underflow;
endproperty // here

// internal signals
property wr_ptr_p;
@(posedge clk) disable iff (rst_n == 0) (wr_en) && (count < FIFO_DEPTH) |=> (wr_ptr == $past(wr_ptr) + 1'b1);
endproperty

property rd_ptr_p;
@(posedge clk) disable iff (rst_n == 0) (rd_en) && (count != 0) |=> (rd_ptr == $past(rd_ptr) + 1'b1);
endproperty

property count_write_priority_p;
@(posedge clk) disable iff (rst_n == 0) (wr_en) && (rd_en) && (empty) |=> (count == $past(count) + 1);
endproperty

property count_read_priority_p;
@(posedge clk) disable iff (rst_n == 0) (wr_en) && (rd_en) && (full) |=> (count == $past(count) - 1);
endproperty

property count_w_p;
@(posedge clk) disable iff (rst_n == 0) (wr_en) && (!rd_en) && (!full) |=> (count == $past(count) + 1);
endproperty

property count_r_p;
@(posedge clk) disable iff (rst_n == 0) (!wr_en) && (rd_en) && (!empty) |=> (count == $past(count) - 1);
endproperty

// Garded Assertions
`ifdef SIM
ack_a: assert property (ack_p);
overflow_a: assert property (overflow_p);
underflow_a: assert property (underflow_p);
wr_ptr_a: assert property (wr_ptr_p);
rd_ptr_a: assert property (rd_ptr_p);
count_write_priority_a: assert property (count_write_priority_p);
count_read_priority_a: assert property (count_read_priority_p);
count_w_a: assert property (count_w_p);
count_r_a: assert property (count_r_p);
`endif

// cover
ack_c: cover property (ack_p);
overflow_c: cover property (overflow_p);
underflow_c: cover property (underflow_p);
wr_ptr_c: cover property (wr_ptr_p);
rd_ptr_c: cover property (rd_ptr_p);
count_write_priority_c: cover property (count_write_priority_p);
count_read_priority_c: cover property (count_read_priority_p);
count_w_c: cover property (count_w_p);
count_r_c: cover property (count_r_p);

always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
wr_ptr <= 0;
wr_ack <= 0; // was added
overflow <= 0; // was added
end
else if (wr_en && count < FIFO_DEPTH) begin
mem[wr_ptr] <= data_in;
wr_ack <= 1;
wr_ptr <= wr_ptr + 1;
overflow <= 0; // was added
end
else begin
wr_ack <= 0;
if (full & wr_en)
overflow <= 1;
else
overflow <= 0;
end
end

always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
rd_ptr <= 0;
underflow <= 0; // was added
end
else if (rd_en && count != 0) begin
data_out <= mem[rd_ptr];
rd_ptr <= rd_ptr + 1;
underflow <= 0; // was added
end
else begin
if(empty && rd_en) // this is sequential output not combinational
underflow = 1;
else
underflow = 0;
end
end

always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
count <= 0;
end
else begin
if (wr_en && rd_en && empty) // this condition was added
count <= count + 1;
else if (wr_en && rd_en && full) // this condition was added
count <= count - 1;
else if ( ({wr_en, rd_en} == 2'b10) && !full)
count <= count + 1;
else if ( ({wr_en, rd_en} == 2'b01) && !empty)
count <= count - 1;
end
end

assign full = (count == FIFO_DEPTH)? 1 : 0;
assign empty = (count == 0)? 1 : 0;
//assign underflow = (empty && rd_en)? 1 : 0; // this was synchronized
assign almostfull = (count == FIFO_DEPTH-1)? 1 : 0;
assign almostempty = (count == 1)? 1 : 0;

endmodule
51 changes: 51 additions & 0 deletions SV Based Verification/FIFO_COVERAGE.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package fifo_coverage_pkg;
import fifo_transaction_pkg::*;
import shared_pkg::*;
class FIFO_coverage;
// fifo_transaction class object
FIFO_transaction F_cvg_txn = new;


// cover group
covergroup FIFO_Cross_Group; // all crosses will be with read enable and write enable and each one of the output signals
// cover points
cp_wr_en: coverpoint F_cvg_txn.wr_en;
cp_rd_en: coverpoint F_cvg_txn.rd_en;
cp_ack: coverpoint F_cvg_txn.wr_ack;
cp_overflow: coverpoint F_cvg_txn.overflow;
cp_full: coverpoint F_cvg_txn.full;
cp_empty: coverpoint F_cvg_txn.empty;
cp_almostfull: coverpoint F_cvg_txn.almostfull;
cp_almostempty: coverpoint F_cvg_txn.almostempty;
cp_underflow: coverpoint F_cvg_txn.underflow;
// cross coverage
wr_ack_C: cross cp_wr_en, cp_rd_en, cp_ack{
illegal_bins zero_zero_one = binsof(cp_wr_en) intersect {0} && binsof(cp_ack) intersect {1};
} // cross coverage for wr_ack, note that a wr_ack can't be done if the wr_en is zero so i made this case illegal
overflow_C: cross cp_wr_en, cp_rd_en, cp_overflow{
illegal_bins zero_w_one = binsof(cp_wr_en) intersect {0} && binsof(cp_overflow) intersect {1};
} // cross coverage for overflow, note that an overflow can't be done if there is no wr_en, so i made it illegal
full_C: cross cp_wr_en, cp_rd_en, cp_full{
illegal_bins one_r_one = binsof(cp_rd_en) intersect {1} && binsof(cp_full) intersect {1};
} // cross coverage for full, note that a full signal can't be riased if there is read process, so i made it illegal
empty_C: cross cp_wr_en, cp_rd_en, cp_empty; // cross coverage for empty
almostfull_C: cross cp_wr_en, cp_rd_en, cp_almostfull; // cross coverage for almostfull signal
almostempty_C: cross cp_wr_en, cp_rd_en, cp_almostempty; // cross coverage for almostempty signal
underflow_C: cross cp_wr_en, cp_rd_en, cp_underflow{
illegal_bins zero_r_one = binsof(cp_rd_en) intersect {0} && binsof(cp_underflow) intersect {1};
} // cross coverage for underflow signal, note that an underflow can't be done if no read operation occurs, so i made it illegal
endgroup

// void function
function void sample_data(FIFO_transaction F_txn);
F_cvg_txn = F_txn;
FIFO_Cross_Group.sample();
endfunction

function new();
FIFO_Cross_Group = new();
endfunction
endclass
endpackage


28 changes: 28 additions & 0 deletions SV Based Verification/FIFO_IF.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
interface fifo_if (clk);
input clk;

parameter FIFO_WIDTH = 16;
parameter FIFO_DEPTH = 8;

// signals
logic [FIFO_WIDTH-1:0] data_in;
logic rst_n, wr_en, rd_en;
logic [FIFO_WIDTH-1:0] data_out;
logic wr_ack, overflow;
logic full, empty, almostfull, almostempty, underflow;

// dut module
modport DUT (
input clk, data_in, rst_n, wr_en, rd_en,
output data_out, wr_ack, overflow, full, empty, almostfull, almostempty, underflow
);
// test module
modport TEST (
output data_in, rst_n, wr_en, rd_en,
input clk, data_out, wr_ack, overflow, full, empty, almostfull, almostempty, underflow
);
// monitor module
modport MONITOR (
input clk, data_in, rst_n, wr_en, rd_en, data_out, wr_ack, overflow, full, empty, almostfull, almostempty, underflow
);
endinterface
40 changes: 40 additions & 0 deletions SV Based Verification/FIFO_MONITOR.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import fifo_transaction_pkg::*;
import fifo_coverage_pkg::*;
import fifo_scoreboard_pkg::*;
import shared_pkg::*;
module fifo_monitor (fifo_if.MONITOR fifoif);
FIFO_transaction tr_mon = new; // transaction object
FIFO_coverage cov_mon = new; // coverage object
FIFO_scoreboard scb_mon = new; // scoreboard object

initial begin
forever begin
#20; // negedge
// assigning interface data to class transaction object
tr_mon.data_in = fifoif.data_in;
tr_mon.rst_n = fifoif.rst_n;
tr_mon.wr_en = fifoif.wr_en;
tr_mon.rd_en = fifoif.rd_en;
tr_mon.data_out = fifoif.data_out;
tr_mon.wr_ack = fifoif.wr_ack;
tr_mon.overflow = fifoif.overflow;
tr_mon.full = fifoif.full;
tr_mon.empty = fifoif.empty;
tr_mon.almostfull = fifoif.almostfull;
tr_mon.almostempty = fifoif.almostempty;
tr_mon.underflow = fifoif.underflow;
// two parallel processes
fork
// process 1
cov_mon.sample_data(tr_mon);
// process 2
scb_mon.check_data(tr_mon);
join
if (test_finished) begin
$display("error count = %0d, correct count = %0d", error_count_out, correct_count_out);
$stop;
end
end
end
endmodule

Loading

0 comments on commit c566669

Please sign in to comment.