FPGARelated.com
Forums

Simulation vs Synthesis

Started by Simon November 30, 2015
So I have a partly-complete design for a 6502 CPU, it's simulating just fine for the implemented opcodes, but when I run synthesis, I get a whole load of "Sequential element (\newSPData_reg[23] ) is unused and will be removed from module execute.", one for each bit in the register, in fact.

I know the logic is *trying* to use this register, I can see the values in the register changing during simulation runs, but I can't for the life of me see why it would be removed - the 'execute' module is basically a case statement, with one of the cases explicitly setting the value of the 'newSPData' register.

Again, in the simulation, I see the case being executed, and the values changing. I guess what I'm looking for is any tips on how to tackle the problem ("The Knowledge", if you will), I've already tried the 'trace through the logic for the case that should trigger the case in question, and see if anything jumps out at me'. I remain un-jumped-out-at [sigh].

I'm happy to send the design if anyone wants to have a look, but it's a chunk of verilog code, so didn't want to paste it here...

Cheers
   Simon.
On 11/30/2015 1:27 AM, Simon wrote:
> So I have a partly-complete design for a 6502 CPU, it's simulating just fine for the implemented opcodes, but when I run synthesis, I get a whole load of "Sequential element (\newSPData_reg[23] ) is unused and will be removed from module execute.", one for each bit in the register, in fact. > > I know the logic is *trying* to use this register, I can see the values in the register changing during simulation runs, but I can't for the life of me see why it would be removed - the 'execute' module is basically a case statement, with one of the cases explicitly setting the value of the 'newSPData' register. > > Again, in the simulation, I see the case being executed, and the values changing. I guess what I'm looking for is any tips on how to tackle the problem ("The Knowledge", if you will), I've already tried the 'trace through the logic for the case that should trigger the case in question, and see if anything jumps out at me'. I remain un-jumped-out-at [sigh]. > > I'm happy to send the design if anyone wants to have a look, but it's a chunk of verilog code, so didn't want to paste it here...
Usually logic is removed because the result is not used anywhere. You can design and simulate a design only to see the synthesizer remove the entire thing if it has no outputs that make it to an I/O pin. So where are the outputs of your register used? Do they actually connect? -- Rick
On 30/11/2015 06:27, Simon wrote:
> So I have a partly-complete design for a 6502 CPU, it's simulating just fine for the implemented opcodes, but when I run synthesis, I get a whole load of "Sequential element (\newSPData_reg[23] ) is unused and will be removed from module execute.", one for each bit in the register, in fact. > > I know the logic is *trying* to use this register, I can see the values in the register changing during simulation runs, but I can't for the life of me see why it would be removed - the 'execute' module is basically a case statement, with one of the cases explicitly setting the value of the 'newSPData' register. > > Again, in the simulation, I see the case being executed, and the values changing. I guess what I'm looking for is any tips on how to tackle the problem ("The Knowledge", if you will), I've already tried the 'trace through the logic for the case that should trigger the case in question, and see if anything jumps out at me'. I remain un-jumped-out-at [sigh]. > > I'm happy to send the design if anyone wants to have a look, but it's a chunk of verilog code, so didn't want to paste it here... > > Cheers > Simon. >
Hi Simon, Before you spend a lot of time analysing the synthesis messages I would suggest you run a gate level simulation. If that fails then start looking at the gate level and warning/note messages. Synthesis tools are quite clever these days and it is not unusual for the synthesis tools to add/remove or merge registers. Good luck, Hans www.ht-lab.com
On Sun, 29 Nov 2015 22:27:00 -0800, Simon wrote:

> So I have a partly-complete design for a 6502 CPU, it's simulating just > fine for the implemented opcodes, but when I run synthesis, I get a > whole load of "Sequential element (\newSPData_reg[23] ) is unused and > will be removed from module execute.", one for each bit in the register, > in fact. > > I know the logic is *trying* to use this register, I can see the values > in the register changing during simulation runs, but I can't for the > life of me see why it would be removed - the 'execute' module is > basically a case statement, with one of the cases explicitly setting the > value of the 'newSPData' register. > > Again, in the simulation, I see the case being executed, and the values > changing. I guess what I'm looking for is any tips on how to tackle the > problem ("The Knowledge", if you will), I've already tried the 'trace > through the logic for the case that should trigger the case in question, > and see if anything jumps out at me'. I remain un-jumped-out-at [sigh]. > > I'm happy to send the design if anyone wants to have a look, but it's a > chunk of verilog code, so didn't want to paste it here... > > Cheers > Simon.
Doesn't the 6502 have a 16-bit or smaller stack pointer? If so, maybe you've declared it bigger than it should be, and the synthesizer is trimming it to what's used? -- www.wescottdesign.com
>I'm happy to send the design if anyone wants to have a look, but >it's a >chunk of verilog code, so didn't want to paste it here... > >Cheers > Simon.
Thats why we have github.com Back probably before you were born somebody created an optimizing compiler that gave an incredible benchmark time until they realized that the benchmark did an huge amount of work to create a result but then never bothered to use it anywhere. All the code was optimised away. John Eaton --------------------------------------- Posted through http://www.FPGARelated.com
In article <450e997a-afd7-4c3d-a181-b324af6ede3c@googlegroups.com>,
Simon  <google@gornall.net> wrote:
>So I have a partly-complete design for a 6502 CPU, it's simulating >just fine for the implemented opcodes, but when I run synthesis, I >get a whole load of "Sequential element (\newSPData_reg[23] ) is >unused and will be removed from module execute.", one for each bit >in the register, in fact. > >I know the logic is *trying* to use this register, I can see the values >in the register changing during simulation runs, but I can't for the >life of me see why it would be removed - the 'execute' module is >basically a case statement, with one of the cases explicitly setting >the value of the 'newSPData' register. > >Again, in the simulation, I see the case being executed, and the >values changing. I guess what I'm looking for is any tips on how to >tackle the problem ("The Knowledge", if you will), I've already >tried the 'trace through the logic for the case that should trigger >the case in question, and see if anything jumps out at me'. I >remain un-jumped-out-at [sigh].
<snip> Simon - just ignore the message and move on. Really. Synthesis optimizations are quite advanced these days - both combinatorial and across registers. Some sort of optimization that may not be obvious to you, may have combined your register bit with another, leaving this one "unused". It's ok. Trust the tool, and just move on. Regards, Mark
Thanks for all the replies, guys :)

On Sunday, November 29, 2015 at 11:51:03 PM UTC-8, rickman wrote:
>=20 > Usually logic is removed because the result is not used anywhere. You=20 > can design and simulate a design only to see the synthesizer remove the=
=20
> entire thing if it has no outputs that make it to an I/O pin. >=20 > So where are the outputs of your register used? Do they actually connect=
? Actually, this may be it. I had tried to counter this by exporting the data= bus (both input and output) in the top-level test-bench module, but thinkin= g about it, the registers it's removing are from code that exercises the BR= K instruction, which only affects the stack-pointer and program-counter, bo= th of which are internal to the CPU in the design as it stands, and the BRK= instruction is currently the only thing to manipulate the stack pointer (I= 'm going alphabetically through the instruction list, and I've only got as = far as EOR :) Sounds like a likely candidate for what the problem is. Presumably once oth= er things start to also reference the stack pointer (eg: PLA - pull accumul= ator from stack, where A is also linked to the data-bus via other instructi= ons) it will sort itself out. If this isn't the case, is there any sort of annotation/directive to say "k= eep this stuff, I need it!" - there used to be something in ISE in the synt= hesis directives, but I looked last night, and didn't see anything there in= Vivado 2015.4... On Monday, November 30, 2015 at 8:55:51 AM UTC-8, Tim Wescott wrote:
>=20 > Doesn't the 6502 have a 16-bit or smaller stack pointer? If so, maybe=20 > you've declared it bigger than it should be, and the synthesizer is=20 > trimming it to what's used?
If it were just the bits I know are being unused (the top 8), I'd be fine w= ith that :) The 'execute' module can push up to (currently, using the BRK i= nstruction) 3 bytes of data onto the stack. I had declared a 32-bit exporte= d register in the module to store these (as well as a 2-bit count register = to say how many bytes were waiting), and then the cpu core (once 'execute' = has had its way) gets to actually manipulate the stack pointer by transferr= ing data from the shared port to the actual stack. The problem was that all= 32 bits were being "optimized" away, even though BRK was definitely pushin= g 3 bytes into it. On Monday, November 30, 2015 at 10:26:13 AM UTC-8, Mark Curry wrote:
>=20 > Simon - just ignore the message and move on. Really. > Synthesis optimizations are quite advanced these > days - both combinatorial and across registers. =20 >=20 > Some sort of optimization that may not be obvious to=20 > you, may have combined your register bit with another, > leaving this one "unused". It's ok. Trust the tool,=20 > and just move on.
I see - this dovetails into what Rick is saying above - assuming I'm right = that things won't be able to be optimized away once all the instructions ar= e present.=20 I was just concerned that I was doing all this work, and at the end of the = day I'd have a "cpu" that didn't do very much :)=20 Thanks all, again :) Simon
Simon <google@gornall.net> wrote:
> Thanks for all the replies, guys :)
> On Sunday, November 29, 2015 at 11:51:03 PM UTC-8, rickman wrote:
>> Usually logic is removed because the result is not used anywhere. You >> can design and simulate a design only to see the synthesizer remove the >> entire thing if it has no outputs that make it to an I/O pin.
(snip)
> Actually, this may be it. I had tried to counter this by exporting > the databus (both input and output) in the top-level test-bench > module, but thinking about it, the registers it's removing are > from code that exercises the BRK instruction, which only affects > the stack-pointer and program-counter, both of which are internal > to the CPU in the design as it stands, and the BRK instruction > is currently the only thing to manipulate the stack pointer > (I'm going alphabetically through the instruction list, and > I've only got as far as EOR :)
(snip)
> If this isn't the case, is there any sort of annotation/directive > to say "keep this stuff, I need it!" - there used to be something > in ISE in the synthesis directives, but I looked last night, > and didn't see anything there in Vivado 2015.4...
I believe so, but I haven't tried it. Sometimes I only want to know if a design will fit into a certain FPGA, and not actually do anything with it. In that case, I would not want to optimize things out. Most often, though, when something goes away, the optimizer is right and my design is wrong. It only takes a small mistake to propagate through and remove a lot of logic. I have had, at least once, all logic removed! -- glen
jt_eaton <84408@fpgarelated> wrote:
 
(snip)

> Back probably before you were born somebody created an optimizing > compiler that gave an incredible benchmark time until they realized > that the benchmark did an huge amount of work to create a result but > then never bothered to use it anywhere.
> All the code was optimised away.
There are stories like that, but one I remember is where the code was not optimized away, but all done at compile time. Well, that means almost all optimized away. It was a Fortran benchmark that did complicated calculations using statement functions. Statement functions in Fortran are one line functions, used similar to the way #define is used in C, though at the time it was not usual for them to be expanded inline. The IBM OS/360 Fortran H compiler, from the 1960's, did expand them inline, and also did constant expression evaluation, unlike many other compilers. The resulting code printed out the constant. In the case of FPGAs, it might optimize down to a constant output, with no logic left. -- glen
Mark Curry <gtwrek@sonic.net> wrote:
> In article <450e997a-afd7-4c3d-a181-b324af6ede3c@googlegroups.com>, > Simon <google@gornall.net> wrote: >>So I have a partly-complete design for a 6502 CPU, it's simulating >>just fine for the implemented opcodes, but when I run synthesis, I >>get a whole load of "Sequential element (\newSPData_reg[23] ) is >>unused and will be removed from module execute.", one for each bit >>in the register, in fact.
(snip)
> Simon - just ignore the message and move on. Really. > Synthesis optimizations are quite advanced these > days - both combinatorial and across registers.
Since he did the simulation, that is probably what he should do. Often enough, I test my designs in an FPGA, and optimizing out means the logic is wrong. One I remember was video display logic where the logic was wrong on the video output. Maybe an enable for a tristate output. The result then recursively eliminates logic from that point back, which was everthing except the sync generator. I think the messages are generated in the order that the constant signals are found, so start with the message that comes first. It will say that some signal is constant, often a flip-flop that has a constant output. Find out why.
> Some sort of optimization that may not be obvious to > you, may have combined your register bit with another, > leaving this one "unused". It's ok. Trust the tool, > and just move on.
Yes, combined registers are okay. -- glen