在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 4910|回复: 19

systemverilog_paper_sutherland(论文集合)

[复制链接]
发表于 2009-2-3 15:28:18 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
包括:
2002-HDLCon-paper_SystemVerilog.pdf
2003-DVCon-paper_SystemVerilog.pdf
2003-SNUG-paper_SystemVerilog.pdf
2003-SystemVerilog_white_paper.pdf
2004-Mentor-U2U-paper_SystemVerilog_and_ModelSim.pdf
2004-SNUG-Boston-paper_SystemVerilog_FIFO_Channel.pdf
2004-white-paper_SystemVerilog_is_for_everyone.pdf
2005-DVCon_SystemVerilog_Checklist_paper.pdf
2005-SNUG-paper_SystemVerilog_unique_and_priority.pdf
2006-DVCon_SystemVerilog_synthesis_subset_paper.pdf
2006-SNUG-Boston_standard_gotchas_paper.pdf
2006-SNUG-Europe_SystemVerilog_synthesis_paper.pdf
2006-SNUG-SanJose_SVA_for_designers_paper.pdf
2007-SNUG-SanJose_gotcha_again_paper.pdf

systemverilog_paper_sutherland.tar.gz

2.12 MB, 下载次数: 253 , 下载积分: 资产 -2 信元, 下载支出 2 信元

 楼主| 发表于 2009-2-3 16:22:42 | 显示全部楼层
eetop
 楼主| 发表于 2009-2-5 11:23:01 | 显示全部楼层
The example below models a flip-flop with asynchronous set/reset logic (active low).  The model synthesizes correctly, but there is a corner case where simulation results are incorrect.  What is the corner case?

always_ff @(   posedge clk
            or negedge rst_n     // active-low reset
            or negedge set_n     // active-low set
           )
  if (!rst_n)            // reset has priority over set
    q_out <= ’0;        // reset all bits to zero
  else if (!set_n)
    q_out <= ’1;        // set all bits to one
  else
    q_out <= data_in;    // d input assignment

Answer

This model synthesizes as intended.  However, the model does not work correctly for all simulation conditions.  Consider rst_n going low, which correctly asynchronously resets the flip-flop.  While rst_n is low, set_n goes low.  With both rst_n and set_n low at the same time, the flip-flop will correctly remain in reset, because of the priority coding of reset over set in the model.  Everything is OK so far.  Next, rst_n goes high and set_n stays low.  Since the sensitivity list is only sensitive to leading edges (the negedge of rst_n and set_n), the release of rst_n will not trigger the sensitivity list.  This means that the flip-flop will be in a reset state when only the set signal is active.  Gotcha!

This gotcha only exists with synthesizable asynchronous set/reset flip-flops, and will only be evident until the next clock.  The next clock will cause the if...else decisions to be re-evaluated and transition the flip-flop to its set state.  The problem is that actual asynchronous set/reset inputs are level sensitive, so when the reset is removed, the active set takes over and drives the flip-flop to its set level.  In the model, however, synthesis rules require the sensitivity list trigger on the leading edges of the set/reset inputs, causing the simulation to differ from actual hardware behavior.

This gotcha is a result of the synthesis-imposed coding style for a set/reset flip-flop.  This style requires that all signals in a sequential-logic sensitivity list be specified with an edge (posedge or negedge).  In order to model accurate simulation behavior, the asynchronous set/reset signals need to be sensitive to all changes on those signals, not just one edge (the leading edge) of those signals.

To avoid this gotcha, a recommended coding style (created by Don Mills of LCDM Engineering) is to:

1) Add a level-sensitive condition to the sensitivity list that triggers on the trailing edge of reset when set is active.

2) Use conditional compilation (`ifdef/`endif) or synthesis pragmas (translate_off/translate_on) to hide the additional sensitivity list condition from synthesis compilers.

Here's the recommended way to code the previous example:

always_ff @(   posedge clk
            or negedge rst_n     // active-low reset
            or negedge set_n     // active-low set
  `ifndef SYNTHESIS  // non-synthesizable simulation code
            or posedge (rst_n & ~set_n) // trailing edge of reset when set is low
  `endif
           )
  if (!rst_n)           // reset has priority over set
    q_out <= ’0;        // reset all bits to zero
  else if (!set_n)
    q_out <= ’1;        // set all bits to one
  else
    q_out <= data_in;   // d input assignment



An alternative coding style (invented by Cliff Cummings many years ago) to avoid this gotcha is to use the verification force/release commands to override the simulation behavior of the synthesizable model. This method requires adding an additional always block to the model, that is hidden from synthesis using conditional compilation. Note that this alternate solution must use Verilog's general_purpose "always" procedural block. It cannot take advantage of SystemVerilog's always_comb procedural block, because always_comb does not allow multiple procedural blocks to write to the same variables.

`ifndef SYNTHESIS  // start non-synthesizable simulation code
always @*
   if (rst_n && !set_n)  force   q_out = 1'b1;
   else                  release q_out;
`endif             // start synthesizable and simulatable code
always_ff @(posedge clk, negedge rst_n, negedge set_n)
  if (!rst_n)           // reset has priority over set
    q_out <= ’0;        // reset all bits to zero
  else if (!set_n)
    q_out <= ’1;        // set all bits to one
  else
    q_out <= data_in;   // d input assignment

Write your synthesis tool supplier!

This simulation versus synthesis mismatch (a gotcha) is due to a coding style that synthesis compilers require.  Synthesis compilers could parse a sensitivity list that would simulate with the behavior of the actual hardware, but you, as a customer, need to let your synthesis tool supplier know that this is important!
 楼主| 发表于 2009-2-5 11:24:56 | 显示全部楼层
The example below is one of those easy coding mistakes to make in Verilog.  Even after using Verilog for more than 20 years, I can still stare at this code for 10 minutes before I see the mistake.  The example code is a simple 4 input multipexer.  But, when the model is simulated, only the values for the a and b inputs are ever passed to the output.  The c and d inputs are never selected, no matter what the value of the select input is.  Why?

module mux4to1 (
  input  [ 1:0] select,
  input  [31:0] a, b, c, d,
  output [31:0] y);

always @(select, a, b, c, d)
  case (select)
    00: y = a;
    01: y = b;
    10: y = c;
    11: y = d;
  endcase
endmodule

Need a hint?  Think of the classic engineering joke, "There are 10 types of people in the world, those that know binary and those that don't."
Answer

The problem is that even though we, as engineers, often think in binary or hexadecimal, the default base in Verilog is decimal.  The lines in the case statement:

    10: y = c;
    11: y = d;

are decoding the decimal values of ten and eleven, not the binary values of two and three.  Since the select variable is only two bits wide, it cannot store a value of ten (1010 in binary) or eleven (1011 in binary).  Therefore, the c and d inputs of the mux will never be selected and assigned to the y output.  Gotcha!

The correct code for this case statement is to specify binary values, as shown below:

always @(select, a, b, c, d)
  case (select)
    2'b00: y = a;
    2'b01: y = b;
    2'b10: y = c;
    2'b11: y = d;
  endcase

The faulty model will get warning messages from lint programs (coding style checkers) and synthesis compilers.  The warning will be that there is a size mismatch between the select input (2 bits wide) and the sizes of the case expressions (32 bits).  These warnings give a clue that something is wrong, but the coding error is still not obvious.

SystemVerilog has a construct that is useful for this example. The "unique case" and "priority case" statements will cause a run-time warning message to be generated any time a case statement is entered and none of the case expressions match.  In SystemVerilog, the following code would generate an warning message each time select has value of two or three:

always_comb
  unique case (select)
    00: y = a;
    01: y = b;
    10: y = c;
    11: y = d;
  endcase

But be careful!  Using "unique" and "priority" case statements would be the right thing to do in this 4-to-1 mux example, but it is not the right thing for every case statement.  These constructs can affect how the model will be synthesized, and the effect might not be what you want in your hardware design.  But that is a topic for some future Quiz and Tip (and a good reason to take a good SystemVerilog training course)!
 楼主| 发表于 2009-2-5 12:03:16 | 显示全部楼层
The following Verilog code seems simple enough. The intent is to filter a 4-bit value and set a flag. Values between 0 and 5, inclusive, set the low flag. Values between 6 and 10, inclusive, set the mid flag. Values greater than 10 do not set either flag

module band_filter (input  wire [3:0] data_in,
                    output reg        low_flag,
                    output reg        mid_flag);

  always @(data_in) begin
    low_flag = 0; mid_flag = 0;  // clear the flags
    if (data_in > 5)
      if (data_in <= 10)
        mid_flag = 1;            // data_in is between 6 and 10, inclusive
    else
      low_flag = 1;              // data_in is less than or equal to 5
  end
endmodule

GOTCHA! If a test loop data_in values of 0 through 15, the result is not what was intended. The mid flag is correct, but the low_flag is set for the wrong values of data_in.

data_in =  0  low_flag = 0  mid_flag = 0  // ERROR: low_flag shoule be set
data_in =  1  low_flag = 0  mid_flag = 0  // ERROR: low_flag shoule be set
data_in =  2  low_flag = 0  mid_flag = 0  // ERROR: low_flag shoule be set
data_in =  3  low_flag = 0  mid_flag = 0  // ERROR: low_flag shoule be set
data_in =  4  low_flag = 0  mid_flag = 0  // ERROR: low_flag shoule be set
data_in =  5  low_flag = 0  mid_flag = 0  // ERROR: low_flag shoule be set
data_in =  6  low_flag = 0  mid_flag = 1
data_in =  7  low_flag = 0  mid_flag = 1
data_in =  8  low_flag = 0  mid_flag = 1
data_in =  9  low_flag = 0  mid_flag = 1
data_in = 10  low_flag = 0  mid_flag = 1
data_in = 11  low_flag = 1  mid_flag = 0  // ERROR: low_flag shoule be clear
data_in = 12  low_flag = 1  mid_flag = 0  // ERROR: low_flag shoule be clear
data_in = 13  low_flag = 1  mid_flag = 0  // ERROR: low_flag shoule be clear
data_in = 14  low_flag = 1  mid_flag = 0  // ERROR: low_flag shoule be clear
data_in = 15  low_flag = 1  mid_flag = 0  // ERROR: low_flag shoule be clear

What is wrong with this code, and how can you fix it?
Answer

The problem is that, by default, an "else" statement is associated with the nearest preceding "if" statement. This would have been more apparent if the code had been indented differently (and the comments matched what is really happening).

always @(data_in) begin
  low_flag = 0; mid_flag = 0;  // clear the flags
  if (data_in > 5)
    if (data_in <= 10)
      mid_flag = 1;            // data_in is between 6 and 10, inclusive
    else
      low_flag = 1;            // data_in is greater than 10
  end

A good, language-aware editor will do automatic indentation, and make the faulty code more obvious. That is good, but it doesn't fix the problem.

To force the "else" statement to associate with the outer "if" statement, the nested "if" statement needs to be enclosed in a "begin...end" block. This makes the nested "if" statement a self-contained block. The "else" statement that follows will now associate with the outer "if" statement, which is what was intended in this example. The correct code is:

always @(data_in) begin
  low_flag = 0; mid_flag = 0;  // clear the flags
  if (data_in > 5)
    begin
      if (data_in <= 10)
        mid_flag = 1;          // data_in is between 6 and 10, inclusive
    end
  else
    low_flag = 1;              // data_in is less than or equal to 5
end
发表于 2009-4-19 01:35:25 | 显示全部楼层
Thanks a lot !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
发表于 2009-5-12 20:58:47 | 显示全部楼层
bu cuo a a
发表于 2010-3-9 14:11:59 | 显示全部楼层
study it
发表于 2010-5-23 09:15:24 | 显示全部楼层
好东西哦,顶!
发表于 2014-7-21 15:46:24 | 显示全部楼层
谢谢分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条

小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-11-16 18:49 , Processed in 0.024830 second(s), 10 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表