Jump to content

apb_master (in UVM examples) read task is having an issue


Recommended Posts

following are codes from apb_master read task

      this.sigs.mck.paddr   <= addr;
      this.sigs.mck.pwrite  <= '0;
      this.sigs.mck.psel    <= '1;
      @ (this.sigs.mck);
      this.sigs.mck.penable <= '1;
      @ (this.sigs.mck);
      data = this.sigs.mck.prdata;
      this.sigs.mck.psel    <= '0;
      this.sigs.mck.penable <= '0;

Here sigs is virtual interface for apb_if and mck is clocking block defined in apb_if. paddr, pwrite, psel and penable are output signals with no skew (ie default skew of #0) (please refer apb_master class in example codes supplied by accellera) and prdata is input signal with no skew (ie default skew of #1step). Now in above codes, before an event on mck (ie 1st @ (this.sigs.mck)) , output paddr, pwrite and psel are driven, which values effectively appear on corresponding (paddr, pwite and ppsel) interface signals in re-NBA region of posedge clk event. penable clockvar is driven (this.sigs.mck.penable <= '1) after observed region of the same 1st clock event. Now refer following dut.sv codes in codec example, which supplies read data.

always @ (posedge clk)

   if (rst) begin
   else begin

      // Wait for a SETUP+READ or ENABLE+WRITE cycle
      if (apb.psel == 1'b1 && apb.penable == apb.pwrite) begin
         pr_data <= 32'h0;
         if (apb.pwrite) begin
            casex (apb.paddr)
             16'h0000: if (apb.pwdata[8]) SA = 0;
         else begin
            casex (apb.paddr)
             16'h0000: pr_data <= IntReq;
             16'h0004: pr_data <= IntMask;
             16'h0010: pr_data <= TxEn;
             16'h0014: pr_data <= TxLWM;
             16'h0020: pr_data <= {aligned, RxEn};



if condition of apb.psel == 1 and apb.penable == apb.pwrite (when both penable and pwrite are 1'b0) is true in 2nd clock cycle and pr_data local variable in dut is driven with data value using non-blocking assignment. so updated pr_data will be available after NBA region of 2nd clock tick, Now look at apb_master code that local var data (which is output port in read task) is receiving value from clockvar prdata (data = this.sigs.mck.prdata). As per SV (1800-2012) specification this event will be executed in observed region and prdata input clockvar will be updated when interface signal prdata is updated using continuous assign as under (refer dut.sv codes in codec example of UVM)

assign apb.prdata = (apb.psel && apb.penable && !apb.pwrite) ? pr_data : 'z;

here apb.penable becomes 1 only after re-NBA region of 2nd clocking block mck event in apb_master codes. therefore apb.prdata is updated with desired pr_data after re-NBA region while output data is picked-up in observed region (ie before re-NBA region) in same clock cycle, so my simulator is reading 'z value.

Here I am following SV spec (1800-2012), which states that default #0 output skew drives signals in re-NBA region of clocking event, while inputs are updated before clocking block event @ (this.sigs.mck) ie prdata var is updated before observed region.

In my view 1 more clock delay is required before output data is read (data = this.sigs.mck.prdata) in apb_master codes to read correct data from dut or there may be something wrong in my understanding of drives on clockvars. Please , if anyone can help me to understand this issue?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...