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

Incorrect translation in comparation #372

Open
Pusiol opened this issue Jun 19, 2022 · 3 comments
Open

Incorrect translation in comparation #372

Pusiol opened this issue Jun 19, 2022 · 3 comments
Labels

Comments

@Pusiol
Copy link

Pusiol commented Jun 19, 2022

System information

MyHDL Version: 0.11
Python Version: 3.8.10

Well, i dont know if it is a known bug, i am new here. In a little state machine, this sample:

    @always(clk.posedge)
    def core_rot():
        if ct == 0:
            out_vld.next = 0
            if in_vld==1:
                ct.next = 1
        elif ct == (n-1):
            out_vld.next = 1
            ct.next = 0
        else:
            ct.next = ct+1

Is translated into this:

  always @(posedge clk) begin: CK_HDL_CORE_ROT
      case (ct)
          'h0: begin
              out_vld <= 0;
              if ((in_vld == 1)) begin
                  ct <= 1;
              end
          end
          (-'h1): begin
              out_vld <= 1;
              ct <= 0;
          end
          default: begin
              ct <= (ct + 1);
          end
      endcase
  end

Which obviously doesn't work as expected. If you use this identical alternative below, the code is translated correctly.

        elif ct > (n-2):
            ...

In verilog:

        else if (($signed({1'b0, ct}) > (5 - 2))) begin
            ...
        end
@Pusiol Pusiol added the bug label Jun 19, 2022
@josyb josyb removed the bug label Jun 19, 2022
@josyb
Copy link
Contributor

josyb commented Jun 19, 2022

Can you tell me what n in (n-1)stands for?

@Pusiol
Copy link
Author

Pusiol commented Jun 19, 2022

In my original code n was an iteration limiter, but here it's just an integer constant.

Here is an example code that reproduces the error.


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from myhdl import *
import os
native_simulation = 0

@block
def ck_hdl(clk, in_vld, out_vld):
    n=5
    ct = Signal(intbv(0, min=0, max=n+2))

    @always(clk.posedge)
    def core_rot():
        if ct == 0:
            out_vld.next = 0
            if in_vld==1:
                ct.next = 1
        elif ct == (n-1):      # F
#        elif ct > (n-2):       # S
#        elif ct == (5-1):      # F
#        elif ct == (6-2):      # F
#        elif ct == (4):        # S
#        elif ct == (3+1):      # F
            out_vld.next = 1
            ct.next = 0
        else:
            ct.next = ct+1

    return core_rot

def ck_hdl_c(clk, in_vld, out_vld):
    os.system("iverilog -o ck_hdl.o ck_hdl.v tb_ck_hdl.v")
    return Cosimulation("vvp -m /home/eric/git/myhdl/cosimulation/icarus/myhdl.vpi ck_hdl.o", **locals())

def test(clk, in_vld, out_vld):
    len_sim = 6*3
    overclk = 3
    ct_overclk = 0
    for ii in range(len_sim):
        yield clk.posedge
        if ct_overclk > overclk-1:
            ct_overclk = 0
            in_vld.next = 1
        else:
            ct_overclk = ct_overclk+1
            in_vld.next = 0
            if out_vld==1:
                print("qjcqjc")
    raise StopSimulation

if __name__ == '__main__':

    # ports instantiation
    clk = Signal(False)
    in_vld = Signal(False)
    out_vld = Signal(False)

    # design under test
    dut = ck_hdl(clk, in_vld, out_vld)
    dut.convert(hdl='Verilog', initial_values=True)

    if native_simulation == 1:
        dut = ck_hdl_c(clk, in_vld, out_vld)
    
    # clock generator
    def clockgen(clk):
        while True:
            yield delay(10)
            clk.next = not clk

    clock = clockgen(clk)
    check = test(clk, in_vld, out_vld)
    sim = Simulation(clock, dut, check)
    sim.run(quiet=1)

@josyb josyb added the bug label Jun 23, 2022
@josyb
Copy link
Contributor

josyb commented Jul 3, 2022

Eric,

I checked the example
It is an issue of mapping the if elif else chain to a case construct
Whether ' n' is an int or a Signal, the analyser sees the - 1 ( or the + 1) and remembers something entirely wrong as the 'case test value'
So it is a bug after all. I just wonder why it took so many years before someone stumbled over it.
You can work around it either by using the compare as you did or by breaking the if elif else chain into a nested if else if else construct, avoiding the mapping to a case

Best regards,
Josy

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

No branches or pull requests

2 participants