verilog实例-SRAM控制器

一、简介

(1)

(2)

二、Spec

(1)Function descripton

(2)Interface description

Signal Name Width Type Direction Description
clk 1 input System clk signal, 50Mhz
rst 1 input System reset signal,negedge

(3)Block Diagram

在这里插入图片描述

(4)Design detil

  1. List item

(5)Timing

三、Design and Verification

- RTL

SRAM_TOP

/*----------------------------------------------------------
Filename			    :	sram_top
Author					:	deilt
Description				:	sram 可以同时提供读写功能且存取时间区别不大.
Called by				:	
Revision History		:	10/06/2022
                            Revison 1.0
Email					:	[email protected]
Company:Deilt Technology.INC
Copyright(c) 1999, Deilt Technology Inc, All right reserved
--------------------------------------------------------------*/
module sramc_top(
  //input signals
  input wire			hclk,
  input wire			sram_clk,
  input wire    		hresetn,
  input wire    		hsel,
  input wire   	 	    hwrite,
  input wire			hready,
  input wire [2:0]  	hsize ,    
  input wire [2:0]  	hburst,
  input wire [1:0]  	htrans,
  input wire [31:0] 	hwdata,
  input wire [31:0] 	haddr,		
  //Signals for BIST and DFT test mode
  //When signal"dft_en" or "bist_en" is high, sram controller enters into test mode.		
  input wire            dft_en,
  input wire            bist_en,
  
  //output signals
  output wire         	hready_resp,
  output wire [1:0]   	hresp,
  output wire [31:0] 	hrdata,
  //When "bist_done" is high, it shows BIST test is over.
  output wire        	bist_done,
  //"bist_fail" shows the results of each sram funtions.There are 8 srams in this controller.
  output wire [7:0]     bist_fail
  );

  //Select one of the two sram blocks according to the value of sram_csn
  wire [3:0] bank0_csn;
  wire [3:0] bank1_csn;
 
  //Sram read or write signals: When it is high, read sram; low, writesram.
  wire  sram_w_en;

  //Each of 8 srams is 8kx8, the depth is 2^13, so the sram's address width is 13 bits. 
  wire [12:0] sram_addr;

  //AHB bus data write into srams
  wire [31:0] sram_wdata;

  //sram data output data which selected and read by AHB bus
  wire [7:0] sram_q0;
  wire [7:0] sram_q1;
  wire [7:0] sram_q2;
  wire [7:0] sram_q3;
  wire [7:0] sram_q4;
  wire [7:0] sram_q5;
  wire [7:0] sram_q6;
  wire [7:0] sram_q7;

 
  // Instance the two modules:           
  // ahb_slave_if.v and sram_core.v      

  ahb_slave_if  ahb_slave_if_u(
    //-----------------------------------------
    // AHB input signals into sram controller
    //-----------------------------------------
    .hclk     (hclk),
    .hresetn  (hresetn),
    .hsel     (hsel),
    .hwrite   (hwrite),
    .hready   (hready),
    .hsize    (hsize),
    .htrans   (htrans),
    .hburst   (hburst),
    .hwdata   (hwdata),
    .haddr    (haddr),
    
    //-----------------------------------------
    //8 sram blcoks data output into ahb slave
    //interface
    //-----------------------------------------
    .sram_q0   (sram_q0),
    .sram_q1   (sram_q1),
    .sram_q2   (sram_q2),
    .sram_q3   (sram_q3),
    .sram_q4   (sram_q4),
    .sram_q5   (sram_q5),
    .sram_q6   (sram_q6),
    .sram_q7   (sram_q7),

    //---------------------------------------------
    //AHB slave(sram controller) output signals 
    //---------------------------------------------
    .hready_resp  (hready_resp),
    .hresp        (hresp),
    .hrdata       (hrdata),

    //---------------------------------------------
    //sram control signals and sram address  
    //---------------------------------------------
	.sram_w_en    (sram_w_en),
	.sram_addr_out(sram_addr),
     //data write into sram
	.sram_wdata   (sram_wdata),
    //choose the corresponding sram in a bank, active low
    .bank0_csn    (bank0_csn),
    .bank1_csn    (bank1_csn)
	);

  
  sram_core  sram_core_u(
    //AHB bus signals
    .hclk        (hclk    ),
    .sram_clk    (sram_clk),
	.hresetn     (hresetn ),

    //-------------------------------------------
    //sram control singals from ahb_slave_if.v
    //-------------------------------------------
	.sram_addr    (sram_addr ),
	.sram_wdata_in(sram_wdata),
	.sram_wen     (sram_w_en ),
	.bank0_csn    (bank0_csn ),
	.bank1_csn    (bank1_csn ),
     
    //test mode enable signals
	.bist_en      (bist_en   ),
	.dft_en       (dft_en    ),

    //-------------------------------------------
    //8 srams data output into AHB bus
    //-------------------------------------------
    .sram_q0    (sram_q0),
    .sram_q1    (sram_q1),
    .sram_q2    (sram_q2),
    .sram_q3    (sram_q3),
    .sram_q4    (sram_q4),
    .sram_q5    (sram_q5),
    .sram_q6    (sram_q6),
    .sram_q7    (sram_q7),

    //test results output when in test mode
    .bist_done  (bist_done),
    .bist_fail  (bist_fail)
    );
  
endmodule

ahb_slave_if

/*----------------------------------------------------------
Filename			    :	ahb_slave_if
Author					:	deilt
Description				:	
Called by				:	
Revision History		:	10/6/2022
                            Revison 1.0
Email					:	[email protected]
Company:Deilt Technology.INC
Copyright(c) 1999, Deilt Technology Inc, All right reserved
--------------------------------------------------------------*/
module 
#(
    parameter       HADDR_WIDTH     =   32  ,
    parameter       SRAM_ADDR_WIDTH =   13  ,
    parameter       DATA_WIDTH      =   32  ,
    parameter       SRAM_Q_WIDTH    =   8   

)
(
    //-------------------------------------------------
    //AHB port
    //reset and clock
    input                           hclk            ,
    input                           hresetn         ,
    //select
    input                           hsel            ,
    //address and control   
    input                           hready          ,
    input   [HADDR_WIDTH-1:0]       haddr           ,
    input                           hwrite          ,
    input   [1:0]                   htrans          ,
    input   [2:0]                   hsize           ,
    input   [2:0]                   hburst          ,
    //data
    input   [DATA_WIDTH-1:0]        hwdata          ,
    output  [DATA_WIDTH-1:0]        hrdata          ,
    //ahb_slave response    
    output                          hready_resp     ,
    output  [1:0]                   hresp           ,
    //-------------------------------------------------
    //sram  
    input   [SRAM_Q_WIDTH-1:0]      sram_q0         ,
    input   [SRAM_Q_WIDTH-1:0]      sram_q1         ,
    input   [SRAM_Q_WIDTH-1:0]      sram_q2         ,
    input   [SRAM_Q_WIDTH-1:0]      sram_q3         ,
    input   [SRAM_Q_WIDTH-1:0]      sram_q4         ,
    input   [SRAM_Q_WIDTH-1:0]      sram_q5         ,
    input   [SRAM_Q_WIDTH-1:0]      sram_q6         ,
    input   [SRAM_Q_WIDTH-1:0]      sram_q7         ,
    //-------------------------------------------------
    //sram control signal
    output                          sram_w_en       ,   //0:write  1:read
    output  [SRAM_ADDR_WIDTH-1:0]   sram_addr_out   ,   //13bit 8K
    output  [DATA_WIDTH-1:0]        sram_wdata      ,   //write sram data 32bit
    output  [3:0]                   bank0_csn       ,   //low is enable
    output  [3:0]                   bank1_csn       
);

    //htrans[1:0] , in this project ,only in NONSEQ and SEQ can normal operation
    localparam  IDLE    =   2'b00   ,
                BUSY    =   2'b00   ,
                NONSEQ  =   2'b10   ,
                SEQ     =   2'b11   ;

    //ahb slave input signals 
    reg     [HADDR_WIDTH-1:0]       haddr           ;
    reg                             hwrite          ;
    reg     [1:0]                   htrans          ;
    reg     [2:0]                   hsize           ;
    reg     [2:0]                   hburst          ;

    //buf signal
    reg     [HADDR_WIDTH-1:0]       haddr_buf       ;
    reg                             hwrite_buf      ;
    reg     [1:0]                   htrans_buf      ;
    reg     [2:0]                   hsize_buf       ;
    reg     [2:0]                   hburst_buf      ;

    //
    wire    [15:0]                  sram_addr       ;   //haddr---->sram_addr
    wire    [1:0]                   haddr_sramqx_sel;   //Used to select which SRAM to operate and reduce power consumption
    
    wire                            bank_sel        ;
    wire                            sram_csn_en     ;

    wire    [3:0]                   bank0_csn       ;
    wire    [3:0]                   bank1_csn       ;
    wire    [1:0]                   sram_sel        ;
    wire    [1:0]                   hsize_sel       ;
    reg     [3:0]                   sram_csn        ;

    //read or write judgment
    wire                            sram_read       ;
    wire                            sram_write      ;

    //singal cycle transport,hready_resp = 1
    //hrep = okay
    assign  hready_resp   =   1'b1  ;   //singal cycle
    assign  hresp         =   2'b00 ;   // resp is OK

    //generate sram address
    //SRAM 8k*8总寻址64K 0x0--0xffff
    assign  sram_addr           =   haddr[15:0]             ;   //the sram_addr[15] is the minimun of the next bank
    assign  sram_addr_out       =   sram_addr[14:2]         ;   //13bit

    assign  haddr_sramqx_sel    =   haddr[1:0]              ;

    //ahb input delay(buf)
    always @(posedge hclk or negedge hresetn) begin       
        if(!hresetn)begin
            hwrite_buf  <=    1'b0  ; 
            hsize_buf   <=    3'b0  ;
            htrans_buf  <=    2'b0  ;
            hburst_buf  <=    3'b0  ;
            haddr_buf   <=    {
    
    HADDR_WIDTH{
    
    1'b0}}   ;
        end
        else if(hsel && hready)begin        //hsel要片选,否则信号一直在翻转,可能会功能错误,并且功耗大
            hwrite_buf  <=  hwrite  ;       //写SRAM时,把控制信号寄存。因为写操作时,要把地址打一拍,和数据对齐
            hsize_buf   <=  hsize   ;
            htrans_buf  <=  htrans  ;
            hburst_buf  <=  hburst  ;       //可以不用
            haddr_buf   <=  haddr   ;
        end
        else begin
            hwrite_buf  <=    1'b0  ; 
            hsize_buf   <=    3'b0  ;
            htrans_buf  <=    2'b0  ;
            hburst_buf  <=    3'b0  ;
            haddr_buf   <=    {
    
    HADDR_WIDTH{
    
    1'b0}}   ;           
    end
    end

    //write enable && read enable
    assign  sram_read     =   (htrans == NONSEQ || htrans ==  SEQ) && hwrite  ;
    assign  sram_write    =   (htrans == NONSEQ || htrans ==  SEQ) && !hwrite ;
    assign  sram_w_en     =   !sram_write_en   ;

    //sram bank csn
    //低32K bank0 高32K bank1
    //sram_csn_en is mean sram is work
    //sram_csn mean 4bit ,which sram is work 
    assign  sram_csn_en   =   sram_read  ||  sram_write   ;
    assign  bank_sel      =   (sram_csn_en  &&  sram_addr[15] == 1'b0) ? 1'b1 : 1'b0    ;

    //sram 0-7 csn ,determine the hsize[2:0] 8,16,32bits
    //low is valid
    //in bank0_csn  ,which sram is work  
    assign bank0_csn    =   (bank_sel == 1'b1)  ? sram_csn : 4'b1111 ;
    assign bank1_csn    =   (bank_sel == 1'b0 ) ? sram_csn : 4'b1111 ;

    assign  hsize_sel   =   hsize_buf[1:0]  ;   //how many bits
    assign  sram_sel    =   sram_addr[1:0]  ;   //which sram is work 00--1 2 3 4

    always @(*)begin
        if(hsize_sel == 2'b10)    //32bit
            sram_csn    =   4'b0    ;
        else if(hsize_sel == 2'b01)begin  //16bit
            if(sram_sel[1] == 1'b1)
                sram_csn    =   4'b0011 ;
            else
                sram_csn    =   4'b1100 ;
        end
        else if(hsizi_sel == 2'b00)begin  //8bit
            case(sram_sel)
                2'b00 : sram_csn  =  4'b1110 ;
                2'b01 : sram_csn  =  4'b1101 ;
                2'b10 : sram_csn  =  4'b1011 ;
                2'b11 : sram_csn  =  4'b0111 ;
                default:sram_csn  =  4'b1111 ;
            endcase
        end
        else
            sram_csn    =   4'b1111 ;
    end

    //write operation
    assign  sram_wdata = hwdata ;
    //read opretion
    // If bank_sel = 1'b1, bank0 sleceted, or bank1 selected.
    assign hrdata   =   (bank_sel == 1) ? {
    
    sram_q3,sram_q2,sram_q1,sram_q0} : {
    
    sram_q7,sram_q6,sram_q5,sram_q4};

endmodule

sram_core

/*----------------------------------------------------------
Filename			    :	sram_core
Author					: 	deilt
Description				:	同步、单端口SRAM , 例化了8片sram
Called by				:	
Revision History		:	10/06/2022
                            Revison 1.0
Email					:	[email protected]
Company:Deilt Technology.INC
Copyright(c) 1999, Deilt Technology Inc, All right reserved
--------------------------------------------------------------*/
module sram_core(
  //input signals
  input			    hclk,
  input			    sram_clk,
  input			    hresetn,
  
  input			    sram_wen,        // =1 读sram; =0,写sram.8个一起读或者一起写
  input	[12:0]	sram_addr,
  input	[31:0]	sram_wdata_in,   //data write into sram when "sram_wen_in" active low
  input	[3:0]	  bank0_csn,       //两个bank,每个bank有四个片选
  input	[3:0]	  bank1_csn,
  input			    bist_en,         //BIST test mode
  input	    	  dft_en,          //DFT test mode
          
  //output signals
  output [7:0]	sram_q0,
  output [7:0]	sram_q1,
  output [7:0]	sram_q2,
  output [7:0]	sram_q3,
  output [7:0]	sram_q4,
  output [7:0]	sram_q5,
  output [7:0]	sram_q6,
  output [7:0]	sram_q7,
                    
  output			  bist_done,  //When "bist_done" is high, it shows BIST test is over.
  output [7:0]  bist_fail   //"bist_fail" shows the results of each sram funtions.
  );
 
  //Every sram bist's work state and results output.
  wire bist_done0;
  wire bist_fail0;
  wire bist_done1;
  wire bist_fail1;
  wire bist_done2;
  wire bist_fail2;
  wire bist_done3;
  wire bist_fail3;
  wire bist_done4;
  wire bist_fail4;
  wire bist_done5;
  wire bist_fail5;
  wire bist_done6;
  wire bist_fail6;
  wire bist_done7;
  wire bist_fail7;

  wire bank0_bistdone;
  wire bank1_bistdone;

  wire [3:0] bank0_bistfail;
  wire [3:0] bank1_bistfail;

  //bist finishing state of bank0
  assign bank0_bistdone = (bist_done3 && bist_done2) && (bist_done1 && bist_done0);

  //bist results of bank0
  assign bank0_bistfail = {
    
    bist_fail3,bist_fail2,bist_fail1,bist_fail0};

  //bist finishing state of bank1
  assign bank1_bistdone = (bist_done7 && bist_done6) && (bist_done5 && bist_done4);

  //bist results of bank1
  assign bank1_bistfail = {
    
    bist_fail7,bist_fail6,bist_fail5,bist_fail4};

  //--------------------------------------------------------------------------
  //the 8 srams results of BIST test and the finishing state
  //--------------------------------------------------------------------------
  assign bist_done = bank0_bistdone && bank1_bistdone;
  assign bist_fail = {
    
    bank1_bistfail,bank0_bistfail} ;

  //-------------------------------------------------------------------------
  //Instance 8 srams and each provides with BIST and DFT functions. 
  //Bank0 comprises of sram0~sram3, and bank1 comprises of sram4~sram7. 
  //In each bank, the sram control signals broadcast to each sram, and data
  //written per byte into each sram in little-endian style.
  //-------------------------------------------------------------------------
  //bank0 bank1读写使能以及地址都完全相同,写入的数据也相同

  sram_bist u_sram_bist0(
                        .hclk             (hclk),
                        .sram_clk         (sram_clk),
                        .sram_rst_n       (hresetn),
                        .sram_csn_in      (bank0_csn[0]),
                        .sram_wen_in      (sram_wen),
                        .sram_addr_in     (sram_addr),
                        .sram_wdata_in    (sram_wdata_in[7:0]),
                        .bist_en          (bist_en),
		                .dft_en           (dft_en),
                                   
                        .sram_data_out    (sram_q0),
                        .bist_done        (bist_done0),
                        .bist_fail        (bist_fail0)  
                       );

  sram_bist u_sram_bist1(
                        .hclk             (hclk),
                        .sram_clk         (sram_clk),
                        .sram_rst_n       (hresetn),
                        .sram_csn_in      (bank0_csn[1]),
                        .sram_wen_in      (sram_wen),
                        .sram_addr_in     (sram_addr),
                        .sram_wdata_in    (sram_wdata_in[15:8]),
                        .bist_en          (bist_en),
		                .dft_en           (dft_en),
                                   
                        .sram_data_out    (sram_q1),
                        .bist_done        (bist_done1),
                        .bist_fail        (bist_fail1)  
                       );

  sram_bist u_sram_bist2(
                        .hclk             (hclk),
                        .sram_clk         (sram_clk),
                        .sram_rst_n       (hresetn),
                        .sram_csn_in      (bank0_csn[2]),
                        .sram_wen_in      (sram_wen),
                        .sram_addr_in     (sram_addr),
                        .sram_wdata_in    (sram_wdata_in[23:16]),
                        .bist_en          (bist_en),
		                .dft_en           (dft_en),
                                   
                        .sram_data_out    (sram_q2),
                        .bist_done        (bist_done2),
                        .bist_fail        (bist_fail2)  
                       );

  sram_bist u_sram_bist3(
                        .hclk             (hclk),
                        .sram_clk         (sram_clk),
                        .sram_rst_n       (hresetn),
                        .sram_csn_in      (bank0_csn[3]),
                        .sram_wen_in      (sram_wen),
                        .sram_addr_in     (sram_addr),
                        .sram_wdata_in    (sram_wdata_in[31:24]),
                        .bist_en          (bist_en),
		                .dft_en           (dft_en),
                                   
                        .sram_data_out    (sram_q3),
                        .bist_done        (bist_done3),
                        .bist_fail        (bist_fail3)  
                       );

  sram_bist u_sram_bist4(
                        .hclk             (hclk),
                        .sram_clk         (sram_clk),
                        .sram_rst_n       (hresetn),
                        .sram_csn_in      (bank1_csn[0]),
                        .sram_wen_in      (sram_wen),
                        .sram_addr_in     (sram_addr),
                        .sram_wdata_in    (sram_wdata_in[7:0]),
                        .bist_en          (bist_en),
		                .dft_en           (dft_en),
                                   
                        .sram_data_out    (sram_q4),
                        .bist_done        (bist_done4),
                        .bist_fail        (bist_fail4)  
                       );

  sram_bist u_sram_bist5(
                        .hclk             (hclk),
                        .sram_clk         (sram_clk),
                        .sram_rst_n       (hresetn),
                        .sram_csn_in      (bank1_csn[1]),
                        .sram_wen_in      (sram_wen),
                        .sram_addr_in     (sram_addr),
                        .sram_wdata_in    (sram_wdata_in[15:8]),
                        .bist_en          (bist_en),
		                .dft_en           (dft_en),
                                   
                        .sram_data_out    (sram_q5),
                        .bist_done        (bist_done5),
                        .bist_fail        (bist_fail5)  
                       );

  sram_bist u_sram_bist6(
                        .hclk             (hclk),
                        .sram_clk         (sram_clk),
                        .sram_rst_n       (hresetn),
                        .sram_csn_in      (bank1_csn[2]),
                        .sram_wen_in      (sram_wen),
                        .sram_addr_in     (sram_addr),
                        .sram_wdata_in    (sram_wdata_in[23:16]),
                        .bist_en          (bist_en),
		                .dft_en           (dft_en),
                                   
                        .sram_data_out    (sram_q6),
                        .bist_done        (bist_done6),
                        .bist_fail        (bist_fail6)  
                       );
		  
  sram_bist u_sram_bist7(
                        .hclk             (hclk),
                        .sram_clk         (sram_clk),
                        .sram_rst_n       (hresetn),
                        .sram_csn_in      (bank1_csn[3]),
                        .sram_wen_in      (sram_wen),
                        .sram_addr_in     (sram_addr),
                        .sram_wdata_in    (sram_wdata_in[31:24]),
                        .bist_en          (bist_en),
		                .dft_en           (dft_en),
                                     
                        .sram_data_out    (sram_q7),
                        .bist_done        (bist_done7),
                        .bist_fail        (bist_fail7)  
                       );

endmodule

sram_bist

/*----------------------------------------------------------
Filename			      :	mbist_8kx8
Author					    :	deilt
Description				  :	
Called by				    :	
Revision History		:	10/10/2022
                      Revison 1.0
Email					      :	[email protected]
Company:Deilt Technology.INC
Copyright(c) 1999, Deilt Technology Inc, All right reserved
--------------------------------------------------------------*/
module sram_bist(
  //input signals
  input         hclk,
  input         sram_clk,
  input         sram_rst_n,
  input         sram_csn_in,   //chip select enable 
  input         sram_wen_in,   //sram write or read enable; 0:write; 1:read
  input[12:0]   sram_addr_in, 
  input[7:0 ]   sram_wdata_in,
  input         bist_en,       // MBIST mode
  input         dft_en,        // DFT mode
  
  //output signals
  output[7:0 ]  sram_data_out, 
  output        bist_done,     // 1: test over
  output        bist_fail      // high: MBIST Fail
  );
				
  //----------------------------------------------------
  //Internal signals connected the sram with bist module 
  //when "bist_en" active high.
  //----------------------------------------------------
  wire sram_csn;
  wire sram_wen;
  wire sram_oen;
  wire [12:0] sram_a;
  wire [7:0]  sram_d;
  wire [7:0]  data_out;

  //Sram output data when "dft_en" active high.
  wire [7:0] dft_data;
  reg [7:0]  dft_data_r;
 
  wire [12:0] sram_addr;
  wire [7:0]  sram_wdata;

  //clock for bist logic, when bist is not work, clock should be 0.
  wire bist_clk;

  genvar K;
  
  //block sram input when cs is diable for low power design 
  assign sram_addr = sram_csn_in ? 0 : sram_addr_in;
  assign sram_wdata = sram_csn_in ? 0 : sram_wdata_in;

  //dft test result
  assign dft_data = (sram_d ^ sram_a[7:0]) ^ {
    
    sram_csn, sram_wen, sram_oen, sram_a[12:8]}; 

  always @(posedge hclk or negedge sram_rst_n) begin
    if(!sram_rst_n)
      dft_data_r <= 0;
    else if(dft_en)
      dft_data_r <= dft_data;
  end

  //sram data output
  assign sram_data_out = dft_en ? dft_data_r : data_out;
  // Note: Need to take place the mux using the special library cell
/*
  generate for(K = 0; K < 8; K = K+1 )
    begin :hold
    //BHDBWP7T holdQ (.Z(data_out[K]));
    end 
  endgenerate
*/

  //clock for bist logic, when bist is not work, clock should be 0.
  // Note: Need to take place the mux using the special library cell
  // CKMUX2D2BWP7T U_bist_clk_mux (.I0(1'b0), .I1(hclk), .S(bist_en), .Z(bist_clk));
  assign bist_clk = bist_en ? hclk : 1'b0;

  // One sram with BIST and DFT function
  RA1SH u_RA1SH(
        .Q      (data_out),
        .CLK    (sram_clk),
        .CEN    (sram_csn),
        .WEN    (sram_wen),
        .A      (sram_a),
        .D      (sram_d),
        .OEN    (sram_oen)
       );

  mbist_8kx8 u_mbist_8kx8(
        .b_clk   (bist_clk),
        .b_rst_n (sram_rst_n),
        .b_te    (bist_en),
		     //--------------------------------------------------------
		     //All the input signals will be derectly connected to
		     //the sram input when in normal operation; and when in
		     //BIST TEST mode, there are some mux in BIST module
		     //selcting all sram input signals which generated by itself:
		     //sram controll signals, sram write data, etc.
		     //--------------------------------------------------------
         .addr_fun     (sram_addr),
         .wen_fun      (sram_wen_in),
         .cen_fun      (sram_csn_in),
         .oen_fun      (1'b0),
         .data_fun     (sram_wdata),

         .ram_read_out (sram_data_out),
         .data_test    (sram_d),
         .addr_test    (sram_a),
         .wen_test     (sram_wen),
         .cen_test     (sram_csn),
         .oen_test     (sram_oen),

         .b_done       (bist_done),
         .b_fail       (bist_fail)
       );

endmodule

mbist_8kx8

/*----------------------------------------------------------
Filename			      :	mbist_8kx8
Author					    :	deilt
Description				  :	
Called by				    :	
Revision History		:	10/10/2022
                            Revison 1.0
Email					:	[email protected]
Company:Deilt Technology.INC
Copyright(c) 1999, Deilt Technology Inc, All right reserved
--------------------------------------------------------------*/
module mbist_8kx8 
#(parameter WE_WIDTH = 1,
  parameter ADDR_WIDTH = 13,
  parameter DATA_WIDTH = 8
 )
 (
  //input signals
  input                      b_clk,    // bist clock	
  input                      b_rst_n,  // bist resetn
  input                      b_te,     // bist enable
  input [(ADDR_WIDTH-1):0]   addr_fun,
  input [(WE_WIDTH-1):0]     wen_fun,
	input                      cen_fun,
	input                      oen_fun,
	input [(DATA_WIDTH-1):0]   data_fun,
	input [(DATA_WIDTH-1):0]   ram_read_out,
  //output signals
	output [(ADDR_WIDTH-1):0]  addr_test, // address of test
	output [(WE_WIDTH-1):0]    wen_test,  // writing control of bist test mode
	output                     cen_test,  // chip enable control of bist test mode
	output                     oen_test,  // output enable control of bist test mode
  output [(DATA_WIDTH-1):0]  data_test, // data input of bist test mode
	output				             b_done,    // output state of bist test mode
                                        // When "bist_done" is high, it shows BIST test is over.

	output reg                 b_fail     // output result of sram function
                                        // When "bist_fail" is high, the sram function is wrong;
                                        // else, the sram function is right.
  );

  //----------------------------------------------------
  //Define 27 work states of BIST block for bist test
  //----------------------------------------------------
  `define IDEL1         5'b00000
  `define P1_WRITE0     5'b00001
  `define IDEL2         5'b00010
  `define P2_READ0      5'b00011
  `define P2_COMPARE0   5'b00100
  `define P2_WRITE1     5'b00101
  `define IDEL3         5'b00110
  `define P3_READ1      5'b00111
  `define P3_COMPARE1   5'b01000
  `define P3_WRITE0     5'b01001
  `define P3_READ0      5'b01010
  `define P3_COMPARE0   5'b01011
  `define P3_WRITE1     5'b01100
  `define IDEL4         5'b01101
  `define P4_READ1      5'b01110
  `define P4_COMPARE1   5'b01111
  `define P4_WRITE0     5'b10000
  `define IDEL5         5'b10001
  `define P5_READ0      5'b10010
  `define P5_COMPARE0   5'b10011
  `define P5_WRITE1     5'b10100
  `define P5_READ1      5'b10101
  `define P5_COMPARE1   5'b10110
  `define P5_WRITE0     5'b10111
  `define IDEL6         5'b11000
  `define P6_READ0      5'b11001
  `define P6_COMPARE0   5'b11010
  
  // sram address when in bist test mode
  reg [(ADDR_WIDTH-1):0] test_addr;
  
  // bist test end signal
  reg r_end;
  reg r_end_en;
 
  // sram address reset when in bist test mode.
  reg test_addr_rst;

  // sram read or write enable signal when in bist test mode
  reg [(WE_WIDTH-1):0] wen_test_inner;

  // bist start to work in IDLE
  reg rf_start;
  
  // compare the data read from sram with the data written into sram 
  // enable signal
  reg check_en;

  // bist test data source select signal
  // "pattern_sel == 1'b0"-----> test_pattern =  32'b0;
  // "pattern_sel == 1'b1"-----> test_pattern =  32'b1;
  reg pattern_sel;
  wire [(DATA_WIDTH-1):0] test_pattern;
  reg [4:0] cstate, nstate;
  // 1 -- address is goign upward; 0 -- address is going downward
  reg up1_down0; 
  // 1 -- address is stepping; 0 -- address remains
  reg count_en;  

  //-----------------------------------------------------------------
  //     Combinatorial portion
  //-----------------------------------------------------------------
  assign b_done = r_end;
  assign test_pattern = (pattern_sel == 1'b0) ? {DATA_WIDTH{1'b0}} : {
    
    DATA_WIDTH{
    
    1'b1}};

  //--------------------------------------------------------------------
  // The output values of all the mux below will be changed based on the
  // sram whether in normal operation or in bist test mode. 
  //---------------------------------------------------------------------
  assign data_test = (b_te == 1'b1) ? test_pattern   : data_fun;
  assign addr_test = (b_te == 1'b1) ? test_addr      : addr_fun;
  assign wen_test  = (b_te == 1'b1) ? wen_test_inner : wen_fun;
  assign cen_test  = (b_te == 1'b1) ? 1'b0           : cen_fun;
  assign oen_test  = (b_te == 1'b1) ? 1'b0           : oen_fun;

  //--------------------------------------------------------------------
  //    Sequential portion
  //--------------------------------------------------------------------

  //--------------------------------
  // Generate bist work end signal. 
  //--------------------------------
  always @(posedge b_clk , negedge b_rst_n) begin
    if (b_rst_n == 1'b0) 
       r_end<=1'b0;
    else if (r_end_en == 1'b1) 
       r_end<= 1'b1;
       else
         r_end <= 1'b0;
  end
  //----------------------------------------------------
  //          Generate the sram test address.
  // "test_addr_rst " and "up1_down0" decide the mode of 
  // variable the address(increment/decrement). 
  //-----------------------------------------------------
  always @(posedge b_clk , negedge b_rst_n) begin
    if (b_rst_n == 1'b0) 
       test_addr <= {
    
    ADDR_WIDTH{
    
    1'b0}};
    else if (b_te == 1'b1) 
  	  if (test_addr_rst == 1'b1) 
           if (up1_down0 == 1'b1)
          	  test_addr<=  {
    
    ADDR_WIDTH{
    
    1'b0}};
           else
              test_addr<=  {
    
    ADDR_WIDTH{
    
    1'b1}};
     	else
           if (count_en == 1'b1)
               if (up1_down0 == 1'b1)
          	      test_addr<=  test_addr + 1'b1;
               else
                  test_addr<=  test_addr - 1'b1;
  end

  always @(posedge b_clk , negedge b_rst_n)
    if (b_rst_n == 1'b0) 
       b_fail<=1'b1;
    else begin
      //---------------------------------------------------------
      //  When in bist idle1 state, "b_fail" defualt value is "0".
      // --------------------------------------------------------
      if ((b_te == 1'b1) && (rf_start == 1'b1))
          b_fail<=  1'b0;

      //------------------------------------------------------------
      //  "b_fail" value is "1", when data read from sram is different
      // from the expected data wirtten into sram.
      //--------------------------------------------------------------
      if ((b_te == 1'b1) && (check_en == 1'b1) && !(test_pattern == ram_read_out))
          b_fail<=  1'b1;
     end
  
  //------------------------------------------------------------------------------
  //                    Bist test state machine
  //   write "0"(initial sram)                         test_address 0-->1fff
  //   read  "0"------> compare -------->write "1"     test_address 1fff-->0
  //   read  "1"------> compare -------->write "0"     test_address 0-->1fff
  //   write "1"------> read "1"-------->compare       test_address 1fff-->0        
  //   write "0"------> read "0"-------->compare       test_address 0-->1fff        
  //   write "1"------> read "1"-------->compare       test_address 1fff-->0        
  //   write "0"------> read "0"-------->compare       test_address 0-->1fff        
  //------------------------------------------------------------------------------
  always @(posedge b_clk , negedge b_rst_n) begin
    if (b_rst_n == 1'b0) 
          cstate<=`IDEL1;
    else
          cstate<= nstate;
  end
  
  always @(cstate or b_te or r_end or test_addr) begin
    up1_down0     = 1'b1;
    count_en      = 1'b0;
    r_end_en      = 1'b0;
    pattern_sel   = 1'b0;
    test_addr_rst = 1'b0;
    rf_start      = 1'b0;
    check_en      = 1'b0;
    wen_test_inner = {
    
    WE_WIDTH{
    
    1'b1}};
    nstate        = cstate;
    case (cstate)
      `IDEL1 :
          begin
             test_addr_rst = 1'b1;
             if (b_te == 1'b1 && r_end == 1'b0) begin
                   nstate   = `P1_WRITE0;
                   rf_start = 1'b1;
             end
          end
      `P1_WRITE0 :   //initial sram from addr 0~1fff
          begin
    	    count_en       = 1'b1;
    	    wen_test_inner = {
    
    WE_WIDTH{
    
    1'b0}};
    	    pattern_sel    = 1'b0;
             if (test_addr == {
    
    ADDR_WIDTH{
    
    1'b1}} ) begin
                  nstate        = `IDEL2;
                  test_addr_rst = 1'b1;
    	            up1_down0     = 1'b0;
             end
          end
      `IDEL2 :
          begin
    	      pattern_sel   = 1'b0;
    	      up1_down0     = 1'b0;
            test_addr_rst = 1'b1; 
            nstate        = `P2_READ0;
          end
      `P2_READ0 :
          begin
            nstate = `P2_COMPARE0;
          end
      `P2_COMPARE0 :  //compare all "0" data after read from addr 0~1fff
          begin
             pattern_sel = 1'b0;
    	       check_en    = 1'b1;
             nstate      = `P2_WRITE1;
          end
      `P2_WRITE1 :  //all "1" write test from addr 1fff~0
          begin
    	      up1_down0      = 1'b0;
    	      count_en       = 1'b1;
    	      wen_test_inner = {
    
    WE_WIDTH{
    
    1'b0}};
    	      pattern_sel    = 1'b1;
             if (test_addr == {
    
    ADDR_WIDTH{
    
    1'b0}}) begin
                  nstate        = `IDEL3;
                  test_addr_rst = 1'b1;
    	          up1_down0     = 1'b1;
             end
             else
                nstate        = `P2_READ0;
          end
      `IDEL3 :
          begin
             pattern_sel   = 1'b1;
             test_addr_rst = 1'b1;
             nstate        = `P3_READ1;
          end
      `P3_READ1 :
          begin
             nstate = `P3_COMPARE1;
          end
      `P3_COMPARE1 :  //compare all "1" data after read from addr 1fff~0
          begin
            pattern_sel = 1'b1;
            check_en    = 1'b1;
            nstate      = `P3_WRITE0;
          end
      `P3_WRITE0 :
          begin
             wen_test_inner = {
    
    WE_WIDTH{
    
    1'b0}};
             pattern_sel    = 1'b0;
             nstate         = `P3_READ0;
          end
      `P3_READ0 :
          begin
            nstate = `P3_COMPARE0;
          end
      `P3_COMPARE0 :
          begin
            pattern_sel = 1'b0;
            check_en    = 1'b1;
            nstate      = `P3_WRITE1;
          end
      `P3_WRITE1 :
          begin
             wen_test_inner = {
    
    WE_WIDTH{
    
    1'b0}};
             pattern_sel    = 1'b1;
             count_en       = 1'b1;
             if (test_addr == {
    
    ADDR_WIDTH{
    
    1'b1}}) begin
                  nstate        = `IDEL4;
                  test_addr_rst = 1'b1;
             end
             else
                nstate        = `P3_READ1;
          end
      `IDEL4 :   // read all data from addr 1fff~0 and compare with write data "1" every time 
          begin
            pattern_sel   = 1'b1;
            test_addr_rst = 1'b1;
            nstate        = `P4_READ1;
          end
      `P4_READ1 :
          begin
            nstate = `P4_COMPARE1;
          end
      `P4_COMPARE1 :
          begin
            pattern_sel = 1'b1;
            check_en    = 1'b1;
            nstate      = `P4_WRITE0;
          end
      `P4_WRITE0 :
          begin
            wen_test_inner = {
    
    WE_WIDTH{
    
    1'b0}};
            pattern_sel    = 1'b0;
            count_en       = 1'b1;
             if (test_addr == {
    
    ADDR_WIDTH{
    
    1'b1}}) begin
                   nstate        = `IDEL5;
                   test_addr_rst = 1'b1;
             end
             else         
                nstate        = `P4_READ1;
          end
      `IDEL5 :  // read all data from addr 1fff~0 and compare with write data "0" every time 
          begin
             pattern_sel   = 1'b1;
             test_addr_rst = 1'b1;
             nstate        = `P5_READ0;
          end
      `P5_READ0 :
          begin
             nstate = `P5_COMPARE0;
          end
      `P5_COMPARE0 :
          begin
             pattern_sel=1'b0;
             check_en=1'b1;
             nstate = `P5_WRITE1;
          end
      `P5_WRITE1 :
          begin
             wen_test_inner = {
    
    WE_WIDTH{
    
    1'b0}};
             pattern_sel   = 1'b1;
             nstate = `P5_READ1;
          end
      `P5_READ1 :
          begin
             nstate = `P5_COMPARE1;
          end
      `P5_COMPARE1 :
          begin
             pattern_sel=1'b1;
             check_en=1'b1;
             nstate = `P5_WRITE0;
          end
      `P5_WRITE0 :
          begin
             wen_test_inner = {
    
    WE_WIDTH{
    
    1'b0}};
             pattern_sel    = 1'b0;
             count_en       = 1'b1;
             if (test_addr == {
    
    ADDR_WIDTH{
    
    1'b1}}) begin
                   nstate        = `IDEL6;
                   test_addr_rst = 1'b1;
             end
             else
                nstate        = `P5_READ0;
          end
      `IDEL6 :
          begin
             pattern_sel   = 1'b0;
             test_addr_rst = 1'b1;
             nstate        = `P6_READ0;
          end
      `P6_READ0 :
          begin
             nstate        = `P6_COMPARE0;
          end
      `P6_COMPARE0 :
          begin
             pattern_sel = 1'b0;
             check_en    = 1'b1;
             count_en    = 1'b1;
             if (test_addr == {
    
    ADDR_WIDTH{
    
    1'b1}}) begin
                   nstate        = `IDEL1;
                   test_addr_rst = 1'b1;
                   r_end_en      = 1'b1;
             end
             else
                nstate = `P6_READ0;
          end
      default :
          begin
             nstate        = `IDEL1;
             test_addr_rst = 1'b1;
          end 
    endcase
  end

endmodule

ra1sh

/*----------------------------------------------------------
Filename			      :	ra1sh
Author					:	deilt
Description				:	
Called by				:	
Revision History		:	10/10/2022
                        Revison 1.0
Email					   :	[email protected]
Company:Deilt Technology.INC
Copyright(c) 1999, Deilt Technology Inc, All right reserved
--------------------------------------------------------------*/
module RA1SH ( //8K
   Q,
   CLK,
   CEN,
   WEN,
   A,
   D,
   OEN
);
   parameter		   BITS = 8;
   parameter		   word_depth = 8192;
   parameter		   addr_width = 13;
   parameter		   wordx = {
    
    BITS{
    
    1'bx}};
   parameter		   addrx = {
    
    addr_width{
    
    1'bx}};
	
   output [BITS-1:0] Q;
   input CLK;
   input CEN;
   input WEN;
   input [addr_width-1:0] A;
   input [BITS-1:0] D;
   input OEN;

   reg [BITS-1:0]	   mem [word_depth-1:0];

   reg			   NOT_CEN;
   reg			   NOT_WEN;

   reg			   NOT_A0;
   reg			   NOT_A1;
   reg			   NOT_A2;
   reg			   NOT_A3;
   reg			   NOT_A4;
   reg			   NOT_A5;
   reg			   NOT_A6;
   reg			   NOT_A7;
   reg			   NOT_A8;
   reg			   NOT_A9;
   reg			   NOT_A10;
   reg			   NOT_A11;
   reg			   NOT_A12;
   reg [addr_width-1:0]	   NOT_A;
   reg			   NOT_D0;
   reg			   NOT_D1;
   reg			   NOT_D2;
   reg			   NOT_D3;
   reg			   NOT_D4;
   reg			   NOT_D5;
   reg			   NOT_D6;
   reg			   NOT_D7;
   reg [BITS-1:0]	   NOT_D;
   reg			   NOT_CLK_PER;
   reg			   NOT_CLK_MINH;
   reg			   NOT_CLK_MINL;

   reg			   LAST_NOT_CEN;
   reg			   LAST_NOT_WEN;
   reg [addr_width-1:0]	   LAST_NOT_A;
   reg [BITS-1:0]	   LAST_NOT_D;
   reg			   LAST_NOT_CLK_PER;
   reg			   LAST_NOT_CLK_MINH;
   reg			   LAST_NOT_CLK_MINL;


   wire [BITS-1:0]   _Q;
   wire			   _OENi;
   wire [addr_width-1:0]   _A;
   wire			   _CLK;
   wire			   _CEN;
   wire			   _OEN;
   wire                    _WEN;

   wire [BITS-1:0]   _D;
   wire                    re_flag;
   wire                    re_data_flag;


   reg			   LATCHED_CEN;
   reg	                   LATCHED_WEN;
   reg [addr_width-1:0]	   LATCHED_A;
   reg [BITS-1:0]	   LATCHED_D;

   reg			   CENi;
   reg           	   WENi;
   reg [addr_width-1:0]	   Ai;
   reg [BITS-1:0]	   Di;
   reg [BITS-1:0]	   Qi;
   reg [BITS-1:0]	   LAST_Qi;



   reg			   LAST_CLK;





   task update_notifier_buses;
   begin
      NOT_A = {
    
    
               NOT_A12,
	       NOT_A11,
               NOT_A10,
               NOT_A9,
               NOT_A8,
               NOT_A7,
               NOT_A6,
               NOT_A5,
               NOT_A4,
               NOT_A3,
               NOT_A2,
               NOT_A1,
               NOT_A0};
      NOT_D = {
    
    
               NOT_D7,
               NOT_D6,
               NOT_D5,
               NOT_D4,
               NOT_D3,
               NOT_D2,
               NOT_D1,
               NOT_D0};
   end
   endtask

   task mem_cycle;
   begin
      casez({
    
    WENi,CENi})

	2'b10: begin
	   read_mem(1,0);
	end
	2'b00: begin
	   write_mem(Ai,Di);
	   read_mem(0,0);
	end
	2'b?1: ;
	2'b1x: begin
	   read_mem(0,1);
	end
	2'bx0: begin
	   write_mem_x(Ai);
	   read_mem(0,1);
	end
	2'b0x,
	2'bxx: begin
	   write_mem_x(Ai);
	   read_mem(0,1);
	end
      endcase
   end
   endtask
      

   task update_last_notifiers;
   begin
      LAST_NOT_A = NOT_A;
      LAST_NOT_D = NOT_D;
      LAST_NOT_WEN = NOT_WEN;
      LAST_NOT_CEN = NOT_CEN;
      LAST_NOT_CLK_PER = NOT_CLK_PER;
      LAST_NOT_CLK_MINH = NOT_CLK_MINH;
      LAST_NOT_CLK_MINL = NOT_CLK_MINL;
   end
   endtask

   task latch_inputs;
   begin
      LATCHED_A = _A ;
      LATCHED_D = _D ;
      LATCHED_WEN = _WEN ;
      LATCHED_CEN = _CEN ;
      LAST_Qi = Qi;
   end
   endtask


   task update_logic;
   begin
      CENi = LATCHED_CEN;
      WENi = LATCHED_WEN;
      Ai = LATCHED_A;
      Di = LATCHED_D;
   end
   endtask



   task x_inputs;
      integer n;
   begin
      for (n=0; n<addr_width; n=n+1)
	 begin
	    LATCHED_A[n] = (NOT_A[n]!==LAST_NOT_A[n]) ? 1'bx : LATCHED_A[n] ;
	 end
      for (n=0; n<BITS; n=n+1)
	 begin
	    LATCHED_D[n] = (NOT_D[n]!==LAST_NOT_D[n]) ? 1'bx : LATCHED_D[n] ;
	 end
      LATCHED_WEN = (NOT_WEN!==LAST_NOT_WEN) ? 1'bx : LATCHED_WEN ;

      LATCHED_CEN = (NOT_CEN!==LAST_NOT_CEN) ? 1'bx : LATCHED_CEN ;
   end
   endtask

   task read_mem;
      input r_wb;
      input xflag;
   begin
      if (r_wb)
	 begin
	    if (valid_address(Ai))
	       begin
                     Qi=mem[Ai];
	       end
	    else
	       begin
		  Qi=wordx;
	       end
	 end
      else
	 begin
	    if (xflag)
	       begin
		  Qi=wordx;
	       end
	    else
	       begin
	          Qi=Di;
	       end
	 end
   end
   endtask

   task write_mem;
      input [addr_width-1:0] a;
      input [BITS-1:0] d;
 
   begin
      casez({
    
    valid_address(a)})
	1'b0: 
		x_mem;
	1'b1: mem[a]=d;
      endcase
   end
   endtask

   task write_mem_x;
      input [addr_width-1:0] a;
   begin
      casez({
    
    valid_address(a)})
	1'b0: 
		x_mem;
	1'b1: mem[a]=wordx;
      endcase
   end
   endtask

   task x_mem;
      integer n;
   begin
      for (n=0; n<word_depth; n=n+1)
	 mem[n]=wordx;
   end
   endtask

   task process_violations;
   begin
      if ((NOT_CLK_PER!==LAST_NOT_CLK_PER) ||
	  (NOT_CLK_MINH!==LAST_NOT_CLK_MINH) ||
	  (NOT_CLK_MINL!==LAST_NOT_CLK_MINL))
	 begin
	    if (CENi !== 1'b1)
               begin
		  x_mem;
		  read_mem(0,1);
	       end
	 end
      else
	 begin
	    update_notifier_buses;
	    x_inputs;
	    update_logic;
	    mem_cycle;
	 end
      update_last_notifiers;
   end
   endtask

   function valid_address;
      input [addr_width-1:0] a;
   begin
      valid_address = (^(a) !== 1'bx);
   end
   endfunction


   bufif0 (Q[0], _Q[0], _OENi);
   bufif0 (Q[1], _Q[1], _OENi);
   bufif0 (Q[2], _Q[2], _OENi);
   bufif0 (Q[3], _Q[3], _OENi);
   bufif0 (Q[4], _Q[4], _OENi);
   bufif0 (Q[5], _Q[5], _OENi);
   bufif0 (Q[6], _Q[6], _OENi);
   bufif0 (Q[7], _Q[7], _OENi);
   buf (_D[0], D[0]);
   buf (_D[1], D[1]);
   buf (_D[2], D[2]);
   buf (_D[3], D[3]);
   buf (_D[4], D[4]);
   buf (_D[5], D[5]);
   buf (_D[6], D[6]);
   buf (_D[7], D[7]);
   buf (_A[0], A[0]);
   buf (_A[1], A[1]);
   buf (_A[2], A[2]);
   buf (_A[3], A[3]);
   buf (_A[4], A[4]);
   buf (_A[5], A[5]);
   buf (_A[6], A[6]);
   buf (_A[7], A[7]);
   buf (_A[8], A[8]);
   buf (_A[9], A[9]);
   buf (_A[10], A[10]);
   buf (_A[11], A[11]);
   buf (_A[12], A[12]);
   buf (_CLK, CLK);
   buf (_WEN, WEN);
   buf (_OEN, OEN);
   buf (_CEN, CEN);


   assign _OENi = _OEN;
   assign _Q = Qi;
   assign re_flag = !(_CEN);
   assign re_data_flag = !(_CEN || _WEN);


   always @(
	    NOT_A0 or
	    NOT_A1 or
	    NOT_A2 or
	    NOT_A3 or
	    NOT_A4 or
	    NOT_A5 or
	    NOT_A6 or
	    NOT_A7 or
	    NOT_A8 or
	    NOT_A9 or
	    NOT_A10 or
	    NOT_A11 or
	    NOT_A12 or
	    NOT_D0 or
	    NOT_D1 or
	    NOT_D2 or
	    NOT_D3 or
	    NOT_D4 or
	    NOT_D5 or
	    NOT_D6 or
	    NOT_D7 or
	    NOT_WEN or
	    NOT_CEN or
	    NOT_CLK_PER or
	    NOT_CLK_MINH or
	    NOT_CLK_MINL
	    )
      begin
         process_violations;
      end

   always @( _CLK )
      begin
         casez({
    
    LAST_CLK,_CLK})
	   2'b01: begin
	      latch_inputs;
	      update_logic;
	      mem_cycle;
	   end

	   2'b10,
	   2'bx?,
	   2'b00,
	   2'b11: ;

	   2'b?x: begin
	      x_mem;
              read_mem(0,1);
	   end
	   
	 endcase
	 LAST_CLK = _CLK;
      end

   specify 
      $setuphold(posedge CLK, CEN, 1.000, 0.500, NOT_CEN);
      $setuphold(posedge CLK &&& re_flag, WEN, 1.000, 0.500, NOT_WEN);
      $setuphold(posedge CLK &&& re_flag, A[0], 1.000, 0.500, NOT_A0);
      $setuphold(posedge CLK &&& re_flag, A[1], 1.000, 0.500, NOT_A1);
      $setuphold(posedge CLK &&& re_flag, A[2], 1.000, 0.500, NOT_A2);
      $setuphold(posedge CLK &&& re_flag, A[3], 1.000, 0.500, NOT_A3);
      $setuphold(posedge CLK &&& re_flag, A[4], 1.000, 0.500, NOT_A4);
      $setuphold(posedge CLK &&& re_flag, A[5], 1.000, 0.500, NOT_A5);
      $setuphold(posedge CLK &&& re_flag, A[6], 1.000, 0.500, NOT_A6);
      $setuphold(posedge CLK &&& re_flag, A[7], 1.000, 0.500, NOT_A7);
      $setuphold(posedge CLK &&& re_flag, A[8], 1.000, 0.500, NOT_A8);
      $setuphold(posedge CLK &&& re_flag, A[9], 1.000, 0.500, NOT_A9);
      $setuphold(posedge CLK &&& re_flag, A[10], 1.000, 0.500, NOT_A10);
      $setuphold(posedge CLK &&& re_flag, A[11], 1.000, 0.500, NOT_A11);
      $setuphold(posedge CLK &&& re_data_flag, D[0], 1.000, 0.500, NOT_D0);
      $setuphold(posedge CLK &&& re_data_flag, D[1], 1.000, 0.500, NOT_D1);
      $setuphold(posedge CLK &&& re_data_flag, D[2], 1.000, 0.500, NOT_D2);
      $setuphold(posedge CLK &&& re_data_flag, D[3], 1.000, 0.500, NOT_D3);
      $setuphold(posedge CLK &&& re_data_flag, D[4], 1.000, 0.500, NOT_D4);
      $setuphold(posedge CLK &&& re_data_flag, D[5], 1.000, 0.500, NOT_D5);
      $setuphold(posedge CLK &&& re_data_flag, D[6], 1.000, 0.500, NOT_D6);
      $setuphold(posedge CLK &&& re_data_flag, D[7], 1.000, 0.500, NOT_D7);

      $period(posedge CLK, 3.000, NOT_CLK_PER);
      $width(posedge CLK, 1.000, 0, NOT_CLK_MINH);
      $width(negedge CLK, 1.000, 0, NOT_CLK_MINL);

      (CLK => Q[0])=(1.000, 1.000, 0.500, 1.000, 0.500, 1.000);
      (CLK => Q[1])=(1.000, 1.000, 0.500, 1.000, 0.500, 1.000);
      (CLK => Q[2])=(1.000, 1.000, 0.500, 1.000, 0.500, 1.000);
      (CLK => Q[3])=(1.000, 1.000, 0.500, 1.000, 0.500, 1.000);
      (CLK => Q[4])=(1.000, 1.000, 0.500, 1.000, 0.500, 1.000);
      (CLK => Q[5])=(1.000, 1.000, 0.500, 1.000, 0.500, 1.000);
      (CLK => Q[6])=(1.000, 1.000, 0.500, 1.000, 0.500, 1.000);
      (CLK => Q[7])=(1.000, 1.000, 0.500, 1.000, 0.500, 1.000);
      (OEN => Q[0])=(1.000, 1.000, 1.000, 1.000, 1.000, 1.000);
      (OEN => Q[1])=(1.000, 1.000, 1.000, 1.000, 1.000, 1.000);
      (OEN => Q[2])=(1.000, 1.000, 1.000, 1.000, 1.000, 1.000);
      (OEN => Q[3])=(1.000, 1.000, 1.000, 1.000, 1.000, 1.000);
      (OEN => Q[4])=(1.000, 1.000, 1.000, 1.000, 1.000, 1.000);
      (OEN => Q[5])=(1.000, 1.000, 1.000, 1.000, 1.000, 1.000);
      (OEN => Q[6])=(1.000, 1.000, 1.000, 1.000, 1.000, 1.000);
      (OEN => Q[7])=(1.000, 1.000, 1.000, 1.000, 1.000, 1.000);
   endspecify 

endmodule

- Test bench

在这里插入代码片

四、Graph

猜你喜欢

转载自blog.csdn.net/qq_70829439/article/details/127252407