See also: support

Original intent

http://www.asic-world.com/systemverilog/procedure_ctrl2.html

Basically if you have a local scope (ex: a process) and need to declare a local variable, it needs to be in a named scoped because two processes might use the same variable.

What I want

Named blocks should be usable not just when they are required, but also when they are useful. One of the big side effects of this blocks is that they reduce scope. Why?

  • Shorter names to make the code more readable
  • Prevents another bit of code from accidentally using that net
  • Reduces analysis burden on reader: they are guaranteed those signals are not used elsewhere

Ideally I'd want to be able to do two things:

  • Named scope: specify a path prefix that the signals take because I'm going to reference it in a constraint file
  • Anonymous scope: its internal use only. The compiler should automaticly come up with a name because I don't care

Ideally anonymous scope might look like this:

wire in_p, in_n;
wire in_global;
begin
    wire np;

    IBUFDS buff(in_p, in_n, np);
    BUFG buff(np, in_global);
end

And named scope like this:

wire in_p, in_n;
wire in_global;
begin: buff //or buff: begin
    wire np;

    IBUFDS buff(in_p, in_n, np);
    BUFG buff(np, in_global);
end

Such that I could constrain buff/np if I needed to.

It turns out that some of these seem to work in practice, see notes below.

Side note: I haven't thought through the “buff: begin” vs “begin: buff” option that later Verilog versions (SystemVerilog?) brought in. My initial thought though is that while “buff: begin” is slightly cleaner I'm unclear if it was worth it to fragment the language (case study: poor python 3 adoption)

Practical reccomendation

Unfortunately neither of above work (contrast with C where {} do not have to be used with a statement like if). This is the shortest legal version I've been able to come up with:

wire in_p, in_n;
wire in_global;
generate if (1) begin : \_scope\`__LINE__
    wire np;

    IBUFDS buff(in_p, in_n, np);
    BUFG buff(np, in_global);
end endgenerate

Tested ISE 14.5 but I believe this would be legal elsewhere.

How does it work? You evidently can't simply put an if at global scope. However, you can do a generate-if thats always true. We can name this if block and are almost set.

But theres a problem: how to automaticly name it so that the user doesn't have to supply a name? `LINE doesn't work because it adds a space in front of the line number, breaking the identifier. In C you'd do something like:

_scope_ # __LINE__

to concatentate but unfortunately the verilog preprocessor doesn't have a direct equivilent. It does, fortunately, have a nasty near equivilent: abuse escaped literal escaping rules to concatenate the space proceeding the line number. So the first \ declares an escaped literal and the second \ escapes the space that will be generated by LINE.

You could wrap these up in macros if you wanted to, but I've found that it confuses the veditor linter so prefer not to. Also sometimes you want to change to a named scope in which case this version is easy to modify. With this in mind, proposed macros:

//Scope begin
`define SCP_BGN generate if (1) begin : \_scope\`__LINE__
//Scope end
`define SCP_END end endgenerate

wire in_p, in_n;
wire in_global;
`SCP_BGN
    wire np;

    IBUFDS buff(in_p, in_n, np);
    BUFG buff(np, in_global);
`SCP_END

Shorthand

Turns out in ISE 14.5 you can omit the generate/endgeerate:

wire [31:0] my_signal;
if (1) begin : \_scope\`__LINE__
    wire [35:0] control;

    chipscope_icon1 chipscope_icon(
            .CONTROL0(control));
    ila ila(.CONTROL(control), .TRIG0(my_signal));
end

Unfortunately I'm not sure if this is legal and veditor does not like it.

It turns out that we can take this a step further and get what we ideally wanted:

wire [31:0] my_signal;
cs : begin
    wire [35:0] control;

    chipscope_icon1 chipscope_icon(
            .CONTROL0(control));
    ila ila(.CONTROL(control), .TRIG0(my_signal));
end

Which is now very compact but even more questionally legal by the Verilog LRM. Note “cs : begin” is allowed in SystemVerilog over “begin : cs”, but not straight Verilog IIRC.

Constraining

For above, the corresponding .ucf might look something like:

NET "**/cs.chipscope_icon/U0/U_ICON/*/iDRCK_LOCAL" TNM_NET = CS_DRK_CLK ;

Note the use of / to denote modules and . to denote blocks.

 
verilog/named_block.txt · Last modified: 2015/04/06 17:56 by mcmaster-guest
 
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution 4.0 International
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki