|  |  | 
   1 //+++++++++++++++++++++++++++++++++++++++++++++++++
   2 // Define the interface
   3 //+++++++++++++++++++++++++++++++++++++++++++++++++
   4 interface mem_if (input wire clk);
   5   logic        reset;
   6   logic        we_sys;
   7   logic        cmd_valid_sys;
   8   logic        ready_sys;
   9   logic  [7:0] data_sys;
  10   logic  [7:0] addr_sys;
  11   logic        we_mem;
  12   logic        ce_mem;
  13   logic  [7:0] datao_mem;
  14   logic  [7:0] datai_mem;
  15   logic  [7:0] addr_mem;
  16   //=================================================
  17   // Modport for System interface 
  18   //=================================================
  19   modport  system (input clk,reset,we_sys, cmd_valid_sys,
  20                    addr_sys, datao_mem, 
  21                    output we_mem, ce_mem, addr_mem, 
  22                    datai_mem, ready_sys, ref data_sys);
  23   //=================================================
  24   // Modport for memory interface 
  25   //=================================================
  26   modport  memory (input clk,reset,we_mem, ce_mem,
  27                    addr_mem, datai_mem, output datao_mem);
  28   //=================================================
  29   // Modport for testbench 
  30   //=================================================
  31   modport  tb (input clk, ready_sys, 
  32                output reset,we_sys, cmd_valid_sys, addr_sys, 
  33               ref data_sys);
  34 
  35 endinterface
  36 
  37 //+++++++++++++++++++++++++++++++++++++++++++++++++
  38 //  Memory Model 
  39 //+++++++++++++++++++++++++++++++++++++++++++++++++
  40 module memory_model (mem_if.memory mif);
  41 // Memory array
  42 logic [7:0] mem [0:255];
  43 
  44 //=================================================
  45 // Write Logic
  46 //=================================================
  47 always @ (posedge mif.clk)
  48  if (mif.ce_mem && mif.we_mem) begin
  49    mem[mif.addr_mem] <= mif.datai_mem;
  50  end
  51 
  52 //=================================================
  53 // Read Logic
  54 //=================================================
  55 always @ (posedge mif.clk)
  56  if (mif.ce_mem && ~mif.we_mem)  begin
  57    mif.datao_mem <= mem[mif.addr_mem];
  58  end
  59 
  60 endmodule
  61 
  62 //+++++++++++++++++++++++++++++++++++++++++++++++++
  63 //  Memory Controller
  64 //+++++++++++++++++++++++++++++++++++++++++++++++++
  65 module memory_ctrl (mem_if.system sif);
  66 
  67 typedef  enum {IDLE,WRITE,READ,DONE} fsm_t;
  68 
  69 fsm_t state;
  70 
  71 always @ (posedge sif.clk)
  72   if (sif.reset) begin
  73     state         <= IDLE;
  74     sif.ready_sys <= 0;
  75     sif.we_mem    <= 0;
  76     sif.ce_mem    <= 0;
  77     sif.addr_mem  <= 0;
  78     sif.datai_mem <= 0;
  79     sif.data_sys  <= 8'bz;
  80   end else begin
  81     case(state)
  82        IDLE :  begin
  83          sif.ready_sys <= 1'b0;
  84          if (sif.cmd_valid_sys && sif.we_sys) begin
  85            sif.addr_mem   <= sif.addr_sys;
  86            sif.datai_mem  <= sif.data_sys;
  87            sif.we_mem     <= 1'b1;
  88            sif.ce_mem     <= 1'b1;
  89            state          <= WRITE;
  90          end
  91          if (sif.cmd_valid_sys && ~sif.we_sys) begin
  92            sif.addr_mem   <= sif.addr_sys;
  93            sif.datai_mem  <= sif.data_sys;
  94            sif.we_mem     <= 1'b0;
  95            sif.ce_mem     <= 1'b1;
  96            state          <= READ;
  97          end
  98        end
  99        WRITE : begin
 100          sif.ready_sys  <= 1'b1;
 101          if (~sif.cmd_valid_sys) begin
 102            sif.addr_mem   <= 8'b0;
 103            sif.datai_mem  <= 8'b0;
 104            sif.we_mem     <= 1'b0;
 105            sif.ce_mem     <= 1'b0;
 106            state          <= IDLE;
 107          end
 108        end 
 109        READ : begin
 110          sif.ready_sys  <= 1'b1;
 111          sif.data_sys   <= sif.datao_mem;
 112          if (~sif.cmd_valid_sys) begin
 113            sif.addr_mem   <= 8'b0;
 114            sif.datai_mem  <= 8'b0;
 115            sif.we_mem     <= 1'b0;
 116            sif.ce_mem     <= 1'b0;
 117            sif.ready_sys  <= 1'b1;
 118            state          <= IDLE;
 119            sif.data_sys   <= 8'bz;
 120          end 
 121        end 
 122     endcase
 123   end
 124 
 125 endmodule
 126 
 127 //+++++++++++++++++++++++++++++++++++++++++++++++++
 128 // Test  program
 129 //+++++++++++++++++++++++++++++++++++++++++++++++++
 130 program test(mem_if.tb tif);
 131 
 132    initial begin
 133       tif.reset <= 1;
 134       tif.we_sys <= 0;
 135       tif.cmd_valid_sys <= 0;
 136       tif.addr_sys <= 0;
 137       tif.data_sys <= 8'bz;
 138        #100  tif.reset <= 0;
 139       for (int i = 0; i < 4; i ++) begin
 140          @ (posedge tif.clk);
 141          tif.addr_sys <= i;
 142          tif.data_sys <= $random;
 143          tif.cmd_valid_sys <= 1;
 144          tif.we_sys <= 1;
 145          @ (posedge tif.ready_sys);
 146          $display("@%0dns Writing address %0d with data %0x", 
 147              $time, i,tif.data_sys);
 148          @ (posedge tif.clk);
 149          tif.addr_sys <= 0;
 150          tif.data_sys <= 8'bz;
 151          tif.cmd_valid_sys <= 0;
 152          tif.we_sys <= 0;
 153       end
 154       repeat (10) @ (posedge tif.clk);
 155       for (int i= 0; i < 4; i ++) begin
 156          @ (posedge tif.clk);
 157          tif.addr_sys <= i;
 158          tif.cmd_valid_sys <= 1;
 159          tif.we_sys <= 0;
 160          @ (posedge tif.ready_sys);
 161          @ (posedge tif.clk);
 162          $display("@%0dns Reading address %0d, Got data %0x", 
 163            $time, i,tif.data_sys);
 164          tif.addr_sys <= 0;
 165          tif.cmd_valid_sys <= 0;
 166       end
 167        #10  $finish;
 168    end
 169 
 170 endprogram
 171 
 172 //+++++++++++++++++++++++++++++++++++++++++++++++++
 173 //  Testbench
 174 //+++++++++++++++++++++++++++++++++++++++++++++++++
 175 module interface_modports();
 176 
 177 logic clk = 0;
 178 always  #10  clk++;
 179 //=================================================
 180 // Instianciate Interface and DUT 
 181 //=================================================
 182 mem_if miff(clk);
 183 memory_ctrl U_ctrl(miff);
 184 memory_model U_model(miff);
 185 test   U_test(miff);
 186 
 187 endmodule
You could download file interface_modports.sv here | 
|  |  |  @150ns Writing address 0 with data 24
 @230ns Writing address 1 with data 81
 @310ns Writing address 2 with data 9
 @390ns Writing address 3 with data 63
 @690ns Reading address 0, Got data 24
 @770ns Reading address 1, Got data 81
 @850ns Reading address 2, Got data 9
 @930ns Reading address 3, Got data 63
 |