This page has ideas for a Verilog fork akin to the idea of GCC C. It is very incomplete and ad-hoc as things pop into my head

How about Werilog or Veriloh (permutations / advancements)? Weriloh? Interestingly enough Google search corrects Weriloh to Verilog

The specific semantics of say tig vs `tig etc haven't been well throught through

Most of this is biased towards Xilinx tools (xst)

I am not familiar with SystemVerilog. In part, I don't trust the EDA industry and feel they went in the wrong direction, expanding the tools without a solid base. If this goes anywhere, I will take a serious look at SystemVerilog and see if they did anything worth keeping / conforming to

First goal: write a tool that spits out a combination of .v and .ucf to test out this derrived language

Infinite auto assignment

VHDL can do (others ⇒ '0'). In xst 'b0 is limited to 32 bit. 'b0 must be infinite precision. Think I've also ran into situations where maybe for 1 bit it produces warnings

I believe Quartus handles this better than ISE but don't recall exact details

Structures

Must have a structure type that combines multiple signals

Today:

wire my_bus_clk,
wire my_bus_rst,
wire my_bus_data,

Proposed:

struct my_bus begin
    wire clk;
    wire rst;
    wire data;
end
...
my_bus bus,

Timing ignore (TIG) macro

there needs to be a TIG macro to make TIG signals very explicit

Today:

wire my_wire;
(* KEEP = "TRUE" *) wire my_wire_tig_path = sata_din_we;
...
    .my_conn(my_wire_tig_path),

Then a .ucf needs something like:

NET "**/*_tig_path" TIG;

But even this is fragile as xilinx breaks if you don't have at least one _tig_path

Proposal:

    .my_conn(__tig__(my_wire_tig_path)),

Tried this but couldn't match the signal in the .ucf:

function [31:0] tig32;
    input [31:0] in32;
    (* KEEP = "TRUE" *) reg [31:0] func_tig_super_path;
    begin
        func_tig_super_path = in32;
        tig32 = func_tig_super_path;
    end
endfunction

also tried with S, same result

Better warning control

Need to have comprehensive -Werror/-Wno-error like GCC has

unused

Need attribute like gcc's attribute (unused). Probably something like

(* unused *) wire my_signal;

terser begin/end

this is just sugar because I'm lazy, but hey why not

Now:

if (blah) begin
    ...
end else if (blah2) begin
    ...
end

Then:

if (blah) {
    ...
} else if (blah2) {
    ...
}

This may not really be worth breaking things that badly

nested comments / `if 0

In C I find it very helpful to be able to do like this

`if 0
wire my_shitty_signal = 0; /* magic */
...
lots of code
...
`endif

because it gets around nested /* */ issues. Most IDEs work around this by providing a block comment operator that would do something like:

//wire my_shitty_signal = 0; /* magic */
//...
//lots of code
//...

Should not need a special editor for a language to be usable

Function/process

In general these seem poorly implemented

Function return

Return value as name of function is awkward.

function  myfunction_that_computes_stuff;
    input a, b;
begin
    myfunction_that_computes_stuff = a + b;
end
endfunction

Better would be a reserved word for returning function value

function myfunction_that_computes_stuff;
    input a, b;
begin
    ret = a + b;
end
endfunction

Structure

Should resemble modules more closely

function  myfunction
    input a, b;
begin
    myfunction = a + b;
end
endfunction

Propose:

function myfunction(input a, b) begin
    myfunction = a + b;
end

Process/function redundancy

Is there a real difference between the two? Propose eliminating process in favor of function. Proposed: a function can take zero arguments and return no value

Breaking heirarchy

Probably the most contraversial on this page.

HDLs are modeled after hardware instead of thinking about things from a computer perspective. This seems to have made all HDS's heirarchical. This isn't strictly necessary and, while it can be abused, it is very useful to break heirarchy in certain situations. For example, it can be very useful to break out a short lieved debug signal without routing it through the entire heirarchy.

I don't have a solid proposal for how this would look in practice. One idea might be to say that the top level must still have all I/O but it can be assigned from out of the top level. This obviously breaks a lot of assumptions and could be very confusing. Probably need to make a port explicitly non-heirachical

module mein_top(input wire a, input wire b, output wire bc global output wire d)
...
endmodule

where d can be assigned elsewhere by some mechanism. maybe

global.d = 124;

end%%*%% consistency

endmodule/endcase are inconsistent with begin/else used elsewhere.

Now:

module mein_top(input wire a, input wire b, output wire c)
    assign c = a & b;
endmodule

Proposed:

module mein_top(input wire a, input wire b, output wire c) begin
    assign c = a & b;
end

and same idea for case

Preprocessor

Constraints

Somehow need a way for constraints to the preprocessed like the Verilog itself is

oh snap! Quartus allows this: http://forums.xilinx.com/t5/Timing-Analysis/Can-Vivado-handle-timing-constraints-embedded-in-HDL/td-p/350831

variadic macros

absolute must. Model after gcc with VA_ARGS and such

symbol combing

needs C's # operator. Example: allows generating TIG signals through macro

anonymous nets

A lot of verilog design decisions seem to revolve around not creating anonymous signals. But this is already possible per passing {} into signal connections

for example, relaxing this could allow function return to do more

python-esq module argument passing

python's argument passing with *kargs, * *kwargs is very flexible. Should look into adopting something similar

my_module my_module_i(*args, .clk(clk), .a(my_signal), **kwargs);

Module synthesis order

Right now I do something like:

`timescale 1ns / 1ps
`default_nettype none
module my_module
...
endmodule
`default_nettype wire

These attributes should not cary over to other modules. I should then be able to set a compile flag like -Wdefault-nettype=none

Compiler directives in comments

Very mucn not a fan of this. Instead, directives need to be done as symbols that can be pre-processed out depending on the active synthesis tool

Looks like Xilinx also discouarges them (CGD 14.5):

Constraints can also be specified in Verilog code using meta comments. The Verilog
format is the preferred syntax, but the meta comment style is still supported

Instead they reccomend these:

Verilog Attributes Syntax Example One
  (* clock_buffer = "IBUFG" *) input CLK;
Verilog Attributes Syntax Example Two
  (* INIT = "0000" *) reg [3:0] d_out;
Verilog Attributes Syntax Example Three
  always@(current_state or reset)
  begin (* parallel_case *) (* full_case *)
      case (current_state)
Verilog Attributes Syntax Example Four
  (* mult_style = "pipe_lut" *) MULT my_mult (a, b, c);

Optional top level hookup

ISE requires a very strong connection between the .v and the .ucf. One can't, for example, use a generic ML605 .ucf to any of their designs. Pins have to be carefully added and removed to keep the two in sync. One can workaround this by creating a dummy ml605 top module that connects all ports and your design lives in

Unify sync/comb logic

a lot of logic like this:

reg my_nxt, my = 1'b1;
wire my_rising;
always @(posedge clk) begin
    if (rst) begin
        my = 1'b1;
     end else begin
         my = my_nxt;
     end
end

always @(*) begin
    my_nxt = my;
    if (omgwtfbbg) begin
        my_nxt = ~my;
    end
    my_rising = !my && my_nxt
end

Clocks are intrinsic to registers so lets make it so. Also intrinsic is that there is an input (combinatorial) and an output (registered). Both should be successful.

I often find myself doing logic that can be expressed purely in registers but I need to read the combinitorial intermediates. Unfortunately, Verilog does not have an operator to tap these signals.

Proposed simplified version:

@clk, rst:
   logic my(1'b1)
   logic my_rising

   reg:
      if omgwtfbbg:
         my = ~my.
   comb:
       my_rising = !my && my.

Where

  • logic is automatic register / combinatorial (like in SystemVerilog)
  • my register output as “my”
  • my register input as “my.”
  • reg indicates a clocked/registered logic block
  • comb indicates a combintorial logic block
    • Simple example could have been done at global scope as a simple assignment

Note that the registered version can also detect a rising edge but it can only do it the cycle after it happens.

Lambda module

I do stuff like this:

reg3 cdc(
    .din_a(sig_1mhz),
    .clk_b(clk_3mhz),
    .dout_b(sig_3mhz));

my_mod inst(
    .clk(clk_3mhz),
    .din(sig_3mhz));

Which I'd like to write as:

my_mod inst(
    .clk(clk_3mhz),
    .din(reg3(.din_a(sig_1mhz), .clk_b(clk_3mhz))));

Require register

Some sort of attribute that indicates the module input must already be registered. This may be useful to drive optimized CDC primitives

CTA

Must provide rich compile time assertions. These should also extend to constraints such that you can assert things like clocks are within a certain ratio

Shift registers

A common construct is to put several registers are in series. This is useful for CDC, to detect clock edges, and for delay pipelines.

Instead of instantiating register chains directly (that use the same clock), need a way to reference N registers deep.

Verilog:

register [3:0] omgbbq;
wire crazy_output = omgbbq[3];
always @(clk) begin
    omgbbq[0] <= crazy_input;
    omgbbq[3:1] <= omgbbq[2:0];
end

Propose something like:

register omgbbq;
wire crazy_output = omgbbq#3;
always @(clk) begin
    omgbbq <= crazy_input;
end

CDC

Needs a “C runtime library” type thing: build CDC stuff into an accessible library:

  • FIFOs
    • Take STL like approach: post-process the compiled code and keep an IP core cache, generating cores as needed
  • Handshake synchronizer (ie for buses)
  • Global compiler options for number of FF's for metastability protection
    • Standard #define?

Auto clocking

There should be a clkof() operator. Example:

module delay(
        input wire clk,
        input wire din,
        output reg dout);
    always @(posedge clk) begin
        dout <= din;
    end
endmodule

Simplified to:

module delay(
        input wire din,
        output reg dout);
    always @(posedge clkof(din)) begin
        dout <= din;
    end
endmodule

Clock consistency

Add some sort of same clock domain assertion

module and(
        input wire clk,
        input wire dina,
        input wire dinb,
        output reg dout);
    assert_1clk(dina, dinb);
    always @(posedge clk) begin
        dout <= dina && dinb;
    end
endmodule

Or maybe:

module and(
        input wire clk,
        input wire dina,
        input wire dinb,
        output reg dout) __attribute___(oneclk);
    always @(posedge clk) begin
        dout <= dina && dinb;
    end
endmodule

Auto sizing buses

Need a way to reduce repetition where size is implied. Example:

reg [3:0]  data_clk1;
wire [3:0] data_clk2;
cdc cdc(
        .clk1(clk1), .clk1d(data_clk1),
        .clk2(clk2), .clk2d(data_clk2));

Could be something more like:

reg [3:0]  data_clk1;
autosz     data_clk2;
cdc cdc(
        .clk1(clk1), .clk1d(data_clk1),
        .clk2(clk2), .clk2d(data_clk2));

Or maybe even declare it as the output would be better:

reg [3:0]  data_clk1;
cdc cdc(
        .clk1(clk1), .clk1d(data_clk1),
        .clk2(clk2), .clk2d(autosz data_clk2));

Separate policy from implementation

gcc has things like -Werror, -Warn-all, etc. Need to support similar constructs that can be used to tune how loose coding is supported

Clock checking

Consider requiring an explicit waiver to connect signals from different clocks together. -Wcdc?

Following code should generate an error

module mein_mod(
        wire a_clk,
        wire a_dat,
        wire b_clk,
        wire b_dat,
        output wire c);
    reg a_dat_r;
    reg b_dat_r;
    c = a_dat_r && b_dat_r;

    always @(posedge a_clk) begin
        a_dat_r <= a_dat;
    end

    always @(posedge b_clk) begin
        b_dat_r <= b_dat;
    end

Implicit edges

Positive edge is almost always used. It should be the default unless specified explicitly

Backwards compatibility

No backwards compatibility with Verilog nor previous revision of the language itself will be supported for the time being

Anonymous pipelining

var_nxt = stuff <count_reg + 1;

The + 1 adds some unnecessary delay in this case because count_reg is setup before the computation. A few options would be nice such as a TIG

var_nxt = stuff <tig(count_reg + 1);

or ability to register it:

var_nxt = stuff <reg(count_reg + 1);

both options to improve timing without excessive syntax overhead.

Units

led = blink(hz=1, clk=clk)

It should know how fast clk is and be able to calculate the necessary counter value

Module interface operator

Need a way to be able to easily pass a module interface through a hierarchy. Propose that given:

module my_module (input wire a, input wire b, output wire c);

I should be able to do something like:

module big_module(input wire clk, input wire blah, interface(i_my_module));
...
my_module my_module(**i_my_module);

That is, it creates a dictionary that I'm then able to map into the argument space

References

 
verilog/fcv.txt · Last modified: 2016/03/24 18:25 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