I have a simple verilog program that increments a 32 bit counter, converts the number to an ASCII string using $sformat and then pushes the string to the host machine 1 byte at a time using an FTDI FT245RL. Unfortunately Xilinx XST keeps optimizing away the string register vector. I've tried mucking around with various initialization and access routines with no success. I can't seem to turn off optimization, and all of the examples I find online differ very little from my initialization routines. What am I doing wrong? I'm using ISE webpack 10.1, latest patches. module counter(CK12, TXE_, WR, RD_, LED, USBD); input CK12; input TXE_; output WR; output RD_; output [7:0] LED; inout [7:0] USBD; reg [31:0] count = 0; reg [7:0] k; reg wrf = 0; reg rd = 1; reg [7:0] lbyte = 8'b00000000; reg td = 1; parameter MEM_SIZE = 88; parameter STR_SIZE = 11; reg [MEM_SIZE - 1:0] str; reg [7:0] strpos = 8'b00000000; initial begin for (k = 0; k < MEM_SIZE; k = k + 1) begin str[k] = 0; end end always @(posedge CK12) begin if (TXE_ == 0 && wrf == 1) begin count = count + 1; wrf = 0; end else if (wrf == 0) // If we've already lowered the strobe, latch the data begin if(td) begin $sformat(str, "%0000000000d\n", count); strpos = 0; td = 0; end str = str << 8; wrf = 1; strpos = strpos + 1; if(strpos == STR_SIZE) td = 1; end end assign RD_ = rd; assign WR = wrf; assign USBD = str[87:80]; assign LED = count[31:24]; endmodule Loading device for application Rf_Device from file '3s100e.nph' in environment /opt/Xilinx/10.1/ISE. WARNING:Xst:1293 - FF/Latch str_0 has a constant value of 0 in block . This FF/Latch will be trimmed during the optimization process. WARNING:Xst:1896 - Due to other FF/Latch trimming, FF/Latch str_1 has a constant value of 0 in block . This FF/Latch will be trimmed during the optimization process. WARNING:Xst:1896 - Due to other FF/Latch trimming, FF/Latch str_2 has a constant value of 0 in block . This FF/Latch will be trimmed during the optimization process.
Why is XST optimizing away my registers and how do I stop it?
Started by ●April 18, 2009
Reply by ●April 18, 20092009-04-18
On Apr 18, 8:52=A0pm, mooo <randomname...@gmail.com> wrote:> I have a simple verilog program that increments a 32 bit counter, > converts the number to an ASCII string using $sformat and then pushes > the string to the host machine 1 byte at a time using an FTDI FT245RL. > > Unfortunately Xilinx XST keeps optimizing away the string register > vector. I've tried mucking around with various initialization and > access routines with no success. I can't seem to turn off > optimization, and all of the examples I find online differ very little > from my initialization routines. What am I doing wrong? =A0I'm using ISE > webpack 10.1, latest patches. > > module counter(CK12, TXE_, WR, RD_, LED, USBD); > > =A0 =A0input CK12; > =A0 =A0input TXE_; > =A0 =A0output WR; > =A0 =A0output RD_; > =A0 =A0output [7:0] LED; > =A0 =A0inout [7:0] USBD; > > =A0 =A0reg [31:0] count =3D 0; > > =A0 =A0reg [7:0] k; > =A0 =A0reg wrf =A0=3D 0; > =A0 =A0reg rd =A0 =3D 1; > =A0 =A0reg [7:0] lbyte =3D 8'b00000000; > > =A0 =A0reg td =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=3D 1; > =A0 =A0parameter MEM_SIZE =A0=3D 88; > =A0 =A0parameter STR_SIZE =A0=3D 11; > =A0 =A0reg [MEM_SIZE - 1:0] str; > =A0 =A0reg [7:0] strpos =3D 8'b00000000; > > =A0 =A0initial > =A0 =A0 =A0begin > =A0 =A0 =A0 =A0 for (k =3D 0; k < MEM_SIZE; k =3D k + 1) > =A0 =A0 =A0 =A0 =A0 begin > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0str[k] =A0 =A0=3D 0; > =A0 =A0 =A0 =A0 =A0 end > =A0 =A0 =A0end > > =A0 =A0always @(posedge CK12) > =A0 =A0 =A0begin > =A0 =A0 =A0 =A0 if (TXE_ =3D=3D 0 && wrf =3D=3D 1) > =A0 =A0 =A0 =A0 =A0 begin > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0count =A0 =A0=3D count + 1; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0wrf =A0 =A0 =A0 =A0 =3D 0; > =A0 =A0 =A0 =A0 =A0 end > > =A0 =A0 =A0 =A0 else if (wrf =3D=3D 0) =A0// If we've already lowered the=strobe,> latch the data > =A0 =A0 =A0 =A0 =A0 begin > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if(td) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0begin > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 $sformat(str, "%00000=00000d\n", count);> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 strpos =3D 0; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 td =A0 =A0 =3D 0; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0end > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0str =A0 =A0 =A0=3D str << 8; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0wrf =A0 =A0 =A0 =A0 =A0 =A0 =3D 1; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0strpos =A0 =A0 =A0 =A0 =A0=3D strpos +=1;> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if(strpos =3D=3D STR_SIZE) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0td =A0 =A0 =A0 =A0 =A0 =A0=3D 1; > > =A0 =A0 =A0 =A0 =A0 end > =A0 =A0 =A0end > > =A0 =A0assign RD_ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =3D rd; > =A0 =A0assign WR =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=3D wrf; > =A0 =A0assign USBD =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=3D str[87:80]; > =A0 =A0assign LED =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =3D count[31:24=];> > endmodule > > Loading device for application Rf_Device from file '3s100e.nph' in > environment /opt/Xilinx/10.1/ISE. WARNING:Xst:1293 - FF/Latch str_0 > has a constant value of 0 in block . This FF/Latch will be trimmed > during the optimization process. > > WARNING:Xst:1896 - Due to other FF/Latch trimming, FF/Latch str_1 has > a constant value of 0 in block . This FF/Latch will be trimmed during > the optimization process. > > WARNING:Xst:1896 - Due to other FF/Latch trimming, FF/Latch str_2 has > a constant value of 0 in block . This FF/Latch will be trimmed during > the optimization process.what do you think XST should synthesize for $sformat ???? and where did you see synthesizeable samples with $sformat ??? Antti
Reply by ●April 18, 20092009-04-18
I don't know, this is my third verilog program and I'm just tooling around on my lonesome in my spare time. I was googling around trying to figure out how to convert a binary number to an ASCII string and that's what I came up with. How does one tell whether or not something is synthesizeable? I tried looking up what is or isn't supported but wasn't able to find any such document.> what do you think XST should synthesize for $sformat ???? > > and where did you see synthesizeable samples with $sformat ??? > > Antti
Reply by ●April 18, 20092009-04-18
Antti.Lukats@googlemail.com <Antti.Lukats@googlemail.com> wrote:> On Apr 18, 8:52?pm, mooo <randomname...@gmail.com> wrote: >> I have a simple verilog program that increments a 32 bit counter,This is the third post today with the phrase "verilog program" in it. Verilog is not a programming language, it is a hardware description language. If you think of it as programming (at least in the FPGA case) you will get confused.>> converts the number to an ASCII string using $sformat and then pushes >> the string to the host machine 1 byte at a time using an FTDI FT245RL.> what do you think XST should synthesize for $sformat ????I agree, though it should print a message. (It can't be that hard to do, but it will be big and slow.) -- glen
Reply by ●April 18, 20092009-04-18
On Apr 18, 2:26=A0pm, mooo <randomname...@gmail.com> wrote:> I don't know, this is my third verilog program and I'm just tooling > around on my lonesome in my spare time. =A0I was googling around trying > to figure out how to convert a binary number to an ASCII string and > that's what I came up with. =A0How does one tell whether or not > something is synthesizeable? =A0I tried looking up what is or isn't > supported but wasn't able to find any such document. > > > what do you think XST should synthesize for $sformat ???? > > > and where did you see synthesizeable samples with $sformat ??? > > > AnttiThere are a few good books on Verilog with detailed reference to what is or isn't synthesizable. Generally though as soon as you see a dollar-sign as in $sformat you are out of synthesizable range. There are some exceptions like $readmemh which can be used to initialize synthesizable ROMs (for some synthesis tools). The main differrence between this and what you're trying to do is that the main function happens during synthesis for the $readmemh case but must be implemented in hardware for $sformat in your case. There may be some cases where you could use $sformat on a constant and have something synthesize, for example if you were trying to embed today's date in a ROM. In any case the point of the system functions ($...) is that they run on your host system, not the synthesized hardware. There may be available code to do binary to string translation. Doing it yourself would be a great learning exercise, though. Regards, Gabor
Reply by ●April 20, 20092009-04-20
On 2009-04-18, mooo <randomname650@gmail.com> wrote:> I don't know, this is my third verilog program and I'm just tooling > around on my lonesome in my spare time. I was googling around trying > to figure out how to convert a binary number to an ASCII string and > that's what I came up with. How does one tell whether or not > something is synthesizeable?This is what's wrong with almost every Verilog tutorial I've seen. They all start out teaching you about the scripting features of Verilog (which are not synthesizable) and totally fail to make the distinction. What's worse is that most people using those tutorials are software programmers who are easily misled. I would scale back your first attempt to sending an ASCII binary string out your serial port. -- Ben Jackson AD7GD <ben@ben.com> http://www.ben.com/
Reply by ●April 20, 20092009-04-20
On Apr 20, 12:52=A0am, Ben Jackson <b...@ben.com> wrote:> On 2009-04-18, mooo <randomname...@gmail.com> wrote: > > > I don't know, this is my third verilog program and I'm just tooling > > around on my lonesome in my spare time. =A0I was googling around trying > > to figure out how to convert a binary number to an ASCII string and > > that's what I came up with. =A0How does one tell whether or not > > something is synthesizeable? > > This is what's wrong with almost every Verilog tutorial I've seen. =A0The=y> all start out teaching you about the scripting features of Verilog (which > are not synthesizable) and totally fail to make the distinction. =A0What'=s> worse is that most people using those tutorials are software programmers > who are easily misled. > > I would scale back your first attempt to sending an ASCII binary string > out your serial port. > > -- > Ben Jackson AD7GD > <b...@ben.com>http://www.ben.com/Not a bad suggestion, since it skips the binary to decimal step. Printing a hexadecimal string would not be much harder. Cheers, Gabor
Reply by ●April 20, 20092009-04-20
On Apr 18, 2:26=A0pm, mooo <randomname...@gmail.com> wrote:> I don't know, this is my third verilog program and I'm just tooling > around on my lonesome in my spare time. =A0I was googling around trying > to figure out how to convert a binary number to an ASCII string and > that's what I came up with. =A0How does one tell whether or not > something is synthesizeable? =A0I tried looking up what is or isn't > supported but wasn't able to find any such document. > > > what do you think XST should synthesize for $sformat ???? > > > and where did you see synthesizeable samples with $sformat ???Figuring out what is synthesizable is actually pretty easy. Any book or even the tool vendor's help file will show you samples of code to generate registers or basic logic. If you stick with those styles, your code should always be synthesizable. So rather than to "code" your problem in an HDL, try "designing" your hardware to solve the problem and then use the code templates to "describe" your hardware. Otherwise it would be HCL (hardware coding language). Rick
Reply by ●April 21, 20092009-04-21
On Apr 18, 12:52=A0pm, mooo <randomname...@gmail.com> wrote:> I have a simple verilog program that increments a 32 bit counter, > converts the number to an ASCII string using $sformat and then pushes > the string to the host machine 1 byte at a time using an FTDI FT245RL. > > Unfortunately Xilinx XST keeps optimizing away the string register > vector. I've tried mucking around with various initialization and > access routines with no success. I can't seem to turn off > optimization, and all of the examples I find online differ very little > from my initialization routines. What am I doing wrong? =A0I'm using ISE > webpack 10.1, latest patches. > > module counter(CK12, TXE_, WR, RD_, LED, USBD); > > =A0 =A0input CK12; > =A0 =A0input TXE_; > =A0 =A0output WR; > =A0 =A0output RD_; > =A0 =A0output [7:0] LED; > =A0 =A0inout [7:0] USBD; > > =A0 =A0reg [31:0] count =3D 0; > > =A0 =A0reg [7:0] k; > =A0 =A0reg wrf =A0=3D 0; > =A0 =A0reg rd =A0 =3D 1; > =A0 =A0reg [7:0] lbyte =3D 8'b00000000; > > =A0 =A0reg td =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=3D 1; > =A0 =A0parameter MEM_SIZE =A0=3D 88; > =A0 =A0parameter STR_SIZE =A0=3D 11; > =A0 =A0reg [MEM_SIZE - 1:0] str; > =A0 =A0reg [7:0] strpos =3D 8'b00000000; > > =A0 =A0initial > =A0 =A0 =A0begin > =A0 =A0 =A0 =A0 for (k =3D 0; k < MEM_SIZE; k =3D k + 1) > =A0 =A0 =A0 =A0 =A0 begin > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0str[k] =A0 =A0=3D 0; > =A0 =A0 =A0 =A0 =A0 end > =A0 =A0 =A0end > > =A0 =A0always @(posedge CK12) > =A0 =A0 =A0begin > =A0 =A0 =A0 =A0 if (TXE_ =3D=3D 0 && wrf =3D=3D 1) > =A0 =A0 =A0 =A0 =A0 begin > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0count =A0 =A0=3D count + 1; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0wrf =A0 =A0 =A0 =A0 =3D 0; > =A0 =A0 =A0 =A0 =A0 end > > =A0 =A0 =A0 =A0 else if (wrf =3D=3D 0) =A0// If we've already lowered the=strobe,> latch the data > =A0 =A0 =A0 =A0 =A0 begin > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if(td) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0begin > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 $sformat(str, "%00000=00000d\n", count);> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 strpos =3D 0; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 td =A0 =A0 =3D 0; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0end > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0str =A0 =A0 =A0=3D str << 8; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0wrf =A0 =A0 =A0 =A0 =A0 =A0 =3D 1; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0strpos =A0 =A0 =A0 =A0 =A0=3D strpos +=1;> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if(strpos =3D=3D STR_SIZE) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0td =A0 =A0 =A0 =A0 =A0 =A0=3D 1; > > =A0 =A0 =A0 =A0 =A0 end > =A0 =A0 =A0end > > =A0 =A0assign RD_ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =3D rd; > =A0 =A0assign WR =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=3D wrf; > =A0 =A0assign USBD =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=3D str[87:80]; > =A0 =A0assign LED =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =3D count[31:24=];> > endmodule > > Loading device for application Rf_Device from file '3s100e.nph' in > environment /opt/Xilinx/10.1/ISE. WARNING:Xst:1293 - FF/Latch str_0 > has a constant value of 0 in block . This FF/Latch will be trimmed > during the optimization process. > > WARNING:Xst:1896 - Due to other FF/Latch trimming, FF/Latch str_1 has > a constant value of 0 in block . This FF/Latch will be trimmed during > the optimization process. > > WARNING:Xst:1896 - Due to other FF/Latch trimming, FF/Latch str_2 has > a constant value of 0 in block . This FF/Latch will be trimmed during > the optimization process.Don't forget to use non-blocking assignment (<=3D) rather than direct assignment (=3D) for your registers. See: http://www.asic-world.com/tidbits= /blocking.html
Reply by ●April 21, 20092009-04-21
On Sat, 18 Apr 2009 10:52:09 -0700 (PDT), mooo <randomname650@gmail.com> wrote:>I have a simple verilog program that increments a 32 bit counter, >converts the number to an ASCII string using $sformat and then pushes >the string to the host machine 1 byte at a time using an FTDI FT245RL. >...> $sformat(str, "%0000000000d\n", count);The xst document XST.PDF lists verilog system task which are supported (page 415 in xst.pdf version 11.1.0) and all others, including $sformat are ignored. This means that you are effectively not assigning to str register after initialization and it's always zero so it's a very good candidate for optimization. There is also a 1364.1 IEEE Standard for Verilog RTL synthesis document which says that all system tasks should be ignored which has the same outcome. -- Muzaffer Kal DSPIA INC. ASIC/FPGA Design Services http://www.dspia.com





