Re: [myhdl-list] A puzzling error
Brought to you by:
jandecaluwe
From: garyr <ga...@fi...> - 2013-02-17 04:37:01
|
----- Original Message ----- From: "Christopher Felton" <chr...@gm...> To: <myh...@li...> Sent: Saturday, February 16, 2013 12:31 PM Subject: Re: [myhdl-list] A puzzling error > On 2/16/13 8:57 AM, garyr wrote: >> >> ----- Original Message ----- >> From: "Christopher Felton" <chr...@gm...> >> To: <myh...@li...> >> Sent: Saturday, February 16, 2013 4:37 AM >> Subject: Re: [myhdl-list] A puzzling error >> >> >>> On 2/15/13 10:28 PM, garyr wrote: >>>> Below is a portion of the code for a multiplier module that works fine in >>>> its >>>> test bench. It also worked OK as part of a lowpass filter module; that is, >>>> the >>>> filter module test bench didn't reveal any problems. But when the filter >>>> module >>>> is converted to Verilog an error occurs. The -547 is the value assigned to >>>> signal 'multiplier'. As you can see it wasn't negated properly; instead of >>>> (--547) it should be (547). Is this a bug or have I screwed up somewhere? >>>> >>>> elif start == ACTIVE_LOW: >>>> done.next = INACTIVE_HIGH >>>> result.next = 0 >>>> if multiplier >= 0: >>>> mpyVar.next = multiplier >>>> negate.next = 0 >>>> else: >>>> mpyVar.next = -multiplier >>>> negate.next = 1 >>>> >>>> else if ((FA_FO_startm == 0)) begin >>>> FA_FO_donem <= 1; >>>> FA_FO_result <= 0; >>>> if ((-547 >= 0)) begin >>>> FA_FO_MPY_mpyVar <= -547; >>>> FA_FO_MPY_negate <= 0; >>>> end >>>> else begin >>>> FA_FO_MPY_mpyVar <= (--547); >>>> FA_FO_MPY_negate <= 1; >>>> end >>>> >>> >>> >>> Why use "--"? I did the following and it converted ok: >>> >>> >>> ~~~~[MyHDL]~~~~ >>> def m_neglit(clock, reset, ival, tval, oval, T=544): >>> >>> @always_seq(clock.posedge, reset=reset) >>> def hdl(): >>> if ival > (tval << 2): >>> oval.next = -T >>> else: >>> oval.next = --T >>> >>> return hdl >>> >>> ~~~~[Verilog]~~~~ >>> always @(posedge clock, negedge reset) begin: M_NEGLIT_HDL >>> if (reset == 0) begin >>> oval <= 0; >>> end >>> else begin >>> if ((ival > (tval << 2))) begin >>> oval <= (-544); >>> end >>> else begin >>> oval <= (-(-544)); >>> end >>> end >>> end >>> ~~~~~~~~~~~~~~~~~ >>> >>> I tested it with using "T" and using the literal 544 >>> directly in the MyHDL source both methods convert fine. >>> >>> But I imagine your question is: why does it convert to >>> (-(-544))? The converter, typically, will not evaluate >>> the code in the generators, it will convert it (translate >>> line by line), essentially as is (only true for the code >>> in the generators). And the Python parsing does not simplify >>> this expression either, so it is then converted to (-(-544)). >>> >>> The next question is: is this bad? I don't think so, the >>> converted Verilog behaves the same as the MyHDL and there >>> should be no issues with synthesis. >>> >>> Regards, >>> Chris >> >> Sorry, I didn't fully describe the problem. >> >> The signal 'multiplier' received its value from something like: >> multiplier.next = int(-0.26757*DATASF) >> where DATASF had a value of 2**11. MyHDL generated the Verilog text shown >> above >> with two consecutive minus signs. The problem arises when this Verilog is >> loaded into Quartus: >> >> Error (10170): Verilog HDL syntax error at lowpass.v(334) near text "-"; >> expecting "(" File: C:/Documents and Settings/Owner/My >> Documents/Python/MyHDL/AllpassLP/LP3MPY/lowpass.v Line: 334 >> >> Line 334 is: FA_FO_MPY_mpyVar <= (--547); >> >> > > If the converter generated /--547/ sounds like this could > be a bug. But I haven't been able to reproduce conversion > that generates /--547/ versus /(-(-547))/. What version of > Python and MyHDL are you using? > > Regards, > Chris I've written a small bit of code that invokes my multiply module and reproduces the problem. I've indicated the main points below. I would be happy to send you copies of this if you like. The test file is about 50 lines, most of which can be ignored. The multiply file is about 100 lines and includes a test bench. def test(clk, reset, start, done, mresult, mval): State = enum('STATE1', 'STATE2', 'IDLE') state = Signal(State.IDLE) multiplicand, multiplier = [Signal(intbv(0, min=-DATASF, max=DATASF)) for j in range(2)] result = Signal(intbv(0, min=-RESULTSF, max=2*RESULTSF)) startm, donem = [Signal(bool(INACTIVE_HIGH)) for j in range(2)] MPY = smpy(clk, reset, startm, donem, result, multiplicand, mval, \ nbitsdata=NBITSDATA, nbitsresult=NBITSRESULT) *snip* def tov(): clk, reset, start, done = [Signal(bool(0)) for k in range(4)] mresult = Signal(intbv(0, min=-RESULTSF, max=RESULTSF)) toVerilog(test, clk, start, reset, done, mresult, mval=-548) if __name__ == '__main__': tov() This is the interesting portion of the multiply function: def smpy(clk, reset, start, done, result, multiplicand, multiplier, \ nbitsdata=12, nbitsresult=24): *snip* elif start == ACTIVE_LOW: done.next = INACTIVE_HIGH result.next = 0 if multiplier >= 0: mpyVar.next = multiplier negate.next = 0 else: mpyVar.next = -(multiplier) negate.next = 1 |