Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with using localparam during building. RS232 implementation Tinyfpga BX #411

Open
DavidGoedicke opened this issue May 19, 2020 · 5 comments

Comments

@DavidGoedicke
Copy link

The following lines of code cause the system to not build. The verification works.

function integer log2;
input integer v;
begin
log2=0;
while(v>>log2) begin
log2=log2+1;
end end
endfunction
localparam l2o = log2(Oversampling);
reg [l2o-2:0] OversamplingCnt = 0;

I am trying to implement fpga4fun-serialinterface

Sending bytes works fine. However, receiving bytes does not work. It also does not work if I hard-code the above problematic line.

I am new to FPGA and Verilog and so I'll attach my files but any pointers on how to debug this problem would be much appreciated.

best wishes
DG

RS232_RecieverSender.ice.zip

Details:

  • macOS 10 15.4 and windows 10
  • icestudio 0.5.0
  • tinyfpgaBX

Consol output

export APIO_HOME_DIR=/Users/dg/.icestudio/apio; "/Users/dg/.icestudio/venv/bin/apio" build --board TinyFPGA-BX --verbose-arachne -p "/var/folders/l1/kck90q_177g8lpdz99njl07m0000gn/T/icestudio-31628IcBTD1EQFcak"

[Mon May 18 21:00:53 2020] Processing TinyFPGA-BX
--------------------------------------------------------------------------------
yosys -p "synth_ice40 -blif hardware.blif" -q main.v
ERROR: Assert `range_left >= range_right || (range_left == -1 && range_right == 0)' failed in frontends/ast/genrtlil.cc:872.
scons: *** [hardware.blif] Error 1
========================= [ ERROR ] Took 0.39 seconds =========================
@DavidGoedicke DavidGoedicke changed the title Problem with building script with local variables Problem with using localparam during building. RS232 implementation Tinyfpga BX May 19, 2020
@Obijuan
Copy link
Member

Obijuan commented May 20, 2020

This is weird! It should work. I've been able to reproduce it. I will try to isolate the problem to understand what is going on. I will tell you my findings

I am testing using icestudio 0.5.1n200403-dev in Linux

As a workaround, you can just hardcode the Oversampling value constant in the code:

localparam l2o = log2(16);

It will let you synthesize the design

@Obijuan
Copy link
Member

Obijuan commented May 20, 2020

This is the minimal circuit for reproducing the bug:

image

Icestudio File:
bug-min.zip

The verification pass ok, but when sinthesizing this error show up:

bug-screenshot

This is the verilog code generated:

// Code generated by Icestudio 0.5.1n200403
// Wed, 20 May 2020 09:58:10 GMT

`default_nettype none

module main #(
 parameter v7f7647 = 16
) (
 output [7:0] vb2d82b
);
 localparam p1 = v7f7647;
 wire [0:7] w0;
 assign vb2d82b = w0;
 main_v180e25 #(
  .N(p1)
 ) v180e25 (
  .o(w0)
 );
endmodule

module main_v180e25 #(
 parameter N = 0
) (
 output [7:0] o
);
 localparam M=$clog2(N);  //-- M = 4
 localparam K = (M-2);    //-- K = 2
 
 wire [K:0] test = K;     //-- Test = 010
 
 //-- Error: Signal '\test' with invalid width range -1!
endmodule

This generated code seems to be ok (iverilator pass)... so maybe the problem is that there is a bug in the yosys version we are using. This version is:

Yosys 0.9+932 (git sha1 UNKNOWN, x86_64-linux-gnu-g++ 7.3.0-16ubuntu3 -O3 -DNDEBUG)

@Obijuan
Copy link
Member

Obijuan commented May 20, 2020

All right! I've found the problem! Icestudio by default assign a default value of 0, so in the first pass, yosys uses N = 0 and the $clog2(0) function fails, assigning -1 to M
That can be fixed just by adding a default value different from 0. It cannot be done directly in Studio yet, but this is how can be solved in the previous example:

image

A new constant is created with etither the parameterized N value or 16 for de default value. Now it synthesizes ok.

In the case of your RS232-RecierverSender we can declare a second constant: Oversamplig2 that includes de default value and use it for calling the log2 function

//-- Set the default value for oversampling
localparam Oversampling2 = (Oversampling==0) ? 16 : Oversampling;
localparam l2o = log2(Oversampling2);

The rest of the code is the same than before.

This is the fixed circuit (I have not test if it works, just that it synthesized with no error):

RS232_RecieverSender-fixed.zip

When you test it leave a comment here and I will close this issue

@DavidGoedicke
Copy link
Author

Thank you for looking at it. I will try out the changes later today.

A quick "understanding" question: The $clog2() function should work the same as the one that was written in the code (log2)?

@Obijuan
Copy link
Member

Obijuan commented May 21, 2020

A quick "understanding" question: The $clog2() function should work the same as the one that was written in the code (log2)?

Yes. The $clog2() is the verilog system function for that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants