Joseph H Allen wrote: Anyway, I've been trying to figure out if this SPARC is superscalor or not. It does not appear to have any dataflow management logic and the mainregister file is only 5 ports, so I suspect not. ---Yeah, I suspect the existing Verilog is not for a superscalar microarchitecture. Check out http://forum.sun.com/thread.jspa?threadID=28739 . -Shyam
OpenSPARC released
Started by ●March 21, 2006
Reply by ●March 28, 20062006-03-28
Reply by ●March 28, 20062006-03-28
Please provide any evidence of this assertion :
" The price you pay is very large: unmaintainable, unreadable code
which is probably an order of magnitude larger than proper RTL."
This coding style which you so clearly denegrate as sub par, is
actually quite standard among high end chip development. Some reasons :
1) Much easier to swap flop models, because noone is allowed to write
there own always @ flop blocks. To replace the library for flops, it is
as simple as changing an include.
Attempting to do this in a "proper RTL" is actually "unmaintainable".
Experience in porting a design from one technology library to the next
will give you the type of experience that shows these coding standards
are *necessary*, to be able to do this type of work, your "proper RTL"
style is inflexible compared to this.
2) The synthesis tool does not care. If you write up a inverter going
into a flop, or code up a flop with an inverting input, the synthesizer
doesn't care where you placed the code. The final result is the exact
same thing.
Now if you had followed these coding guidelines, swapping out this flop
can be done by tweaking the include path for the library, you would
have to visit every line of code in your design to see whether or not
the always block is actually a flop, and then recode by hand. ( Good if
you get paid by the hour, not so good for your employer ).
3) Rebalancing logic across clock domain crossings is easier when the
logic is seperate from the flop : X's are flops (a,b,c) is assign wires
X1 --> a --> b --> c --> X2
X1 --> a --> b --> X2 --> c
The only changes that need to occur, is the input from the X2 is
changed to be b, instead of c, and the input to c is changed to be the
output of X2 instead of the output of b.
Using "proper RTL", you might have coded "a,b,c" inside of an always
block. You then need to create more wires or modify an always blocks to
pull this logic out, and then hook it up. At the end, after you have
applied your timing fix, the code is larger.
Worse yet, you may have made a mistake. These things tend to happen,
and when you recoded this flop, you have have left some path out, and
have turned it into a latch. These types of mistakes are not possible
to do in a instance -- assign -- assign -- instance methodology.
because "always @(posedge...)" is not allowed in your code, it belong
inside a library.
Now you may say "But I am smarter than that!", well that is nice for
you. But when setting up a coding standard that needs to be used by
hundreds of engineers, and verified by tools, ad-hoc methods of "proper
RTL" get left in the dust behind rigid standards that prevent bad stuff
from happening in the first place.
Please consider that this chip was probably design by a group of
engineers easily topping 100+, there were many compiler tools,
synthesis, and other tools that needed to manipulate this code, and get
meaningful information from it. Having each engineer write in what you
describe as "proper RTL" style is not acceptable in these situations.
It is not flexible enough ( you have to add lines of code just to make
timing fixes), error prone ( you can write logic that is not possible
or available in your library ), and doesn't get you *any* better
results.
I fail to see any benefit from using your "proper RTL" style. If there
is some that would offset the costs I have listed above, I am open to
reconsider. And I realize if you have not been exposed to these ideas
before they may sound like problems that you have not faced. But these
problems are common among large scale IC's that need to be taped out
many technologies, and go through extensive ECO timing fixes to achieve
maximum performance.
-Art
Reply by ●March 28, 20062006-03-28
In article <1143583241.607996.321520@t31g2000cwb.googlegroups.com>, Art Stamness <artstamness@gmail.com> wrote:>1) Much easier to swap flop models, because noone is allowed to write >there own always @ flop blocks. To replace the library for flops, it is >as simple as changing an include.>Attempting to do this in a "proper RTL" is actually "unmaintainable". >Experience in porting a design from one technology library to the next >will give you the type of experience that shows these coding standards >are *necessary*, to be able to do this type of work, your "proper RTL" >style is inflexible compared to this.This only makes sense to me if you have different flops in the same design, otherwise just rename the flop itself to match the one generated by the synthesis tool. So if the real problem is that you have different kinds of flops in the same design, why not just attach an attribute to the 'reg' which becomes the flop? reg [15:0] foo /* synthesis attribute floptype="master_slave_3" */; There is another advantage to this. Definitions in include files are frequently bad because they are global. It is almost always better to use parameters whenever possible- then you can reuse code in different ways by overriding a parameter: parameter main_flop="master_slave_3"; reg [15:0] foo /* synthesis attribute floptype=main_flop */;>2) The synthesis tool does not care. If you write up a inverter going >into a flop, or code up a flop with an inverting input, the synthesizer >doesn't care where you placed the code. The final result is the exact >same thing.It doesn't care if you instantiate an inverter, but it certainly does care if you code up a state machine with a 'case' statement. Also, by instantiating flops, you are not giving the synthesis tool information about the flop: in particular, the flop might have a built in clock-enable pin that you want the synthesis tool to use.>3) Rebalancing logic across clock domain crossings is easier when the >logic is seperate from the flop : X's are flops (a,b,c) is assign wiresWhy are you doing this in source code? Can't your synthesis tool rebalance the logic at this micro level?>Worse yet, you may have made a mistake.Human editing is bad. Make the tool do it.>I fail to see any benefit from using your "proper RTL" style. If there >is some that would offset the costs I have listed above, I am open to >reconsider. And I realize if you have not been exposed to these ideas >before they may sound like problems that you have not faced. But these >problems are common among large scale IC's that need to be taped out >many technologies, and go through extensive ECO timing fixes to achieve >maximum performance.IBM long ago showed that bugs were proportional to the number of lines. Thus anything that reduces the number of lines of code is going to reduce your verification cost, which is substantial. -- /* jhallen@world.std.com (192.74.137.5) */ /* Joseph H. Allen */ int a[1817];main(z,p,q,r){for(p=80;q+p-80;p-=2*a[p])for(z=9;z--;)q=3&(r=time(0) +r*57)/7,q=q?q-1?q-2?1-p%79?-1:0:p%79-77?1:0:p<1659?79:0:p>158?-79:0,q?!a[p+q*2 ]?a[p+=a[p+=q]=q]=q:0:0;for(;q++-1817;)printf(q%79?"%c":"%c\n"," #"[!a[q-1]]);}
Reply by ●March 28, 20062006-03-28
Art, You wrote quite a bit, but I cannot agree with any of your arguments. Art Stamness wrote:> Please provide any evidence of this assertion : > > " The price you pay is very large: unmaintainable, unreadable code > which is probably an order of magnitude larger than proper RTL." > > This coding style which you so clearly denegrate as sub par, is > actually quite standard among high end chip development. Some reasons : >Care to show some examples? What "high end chip" are you talking about?> > 1) Much easier to swap flop models, because noone is allowed to write > there own always @ flop blocks. To replace the library for flops, it is > as simple as changing an include. >If you code your flops in always blocks, this is also true. The flops are simply implied by the synthesis tools.> Attempting to do this in a "proper RTL" is actually "unmaintainable". > Experience in porting a design from one technology library to the next > will give you the type of experience that shows these coding standards > are *necessary*, to be able to do this type of work, your "proper RTL" > style is inflexible compared to this. >Again, I don't see how writing always blocks is "unmaintainable." Maybe I haven't had enough experience to "give me the type of experience." Anyhow, suppose you had instantiated a dff that takes clock, din, clr, and set inputs, and synchronous resets are generated from a mux logic. Now, a new technology library gives you cells that has built-in syncronous reset. To port to this new library, you must manually recode all the synchronous reset logic. Compare this to an always block: you don't need to do anything.> 2) The synthesis tool does not care. If you write up a inverter going > into a flop, or code up a flop with an inverting input, the synthesizer > doesn't care where you placed the code. The final result is the exact > same thing. > > Now if you had followed these coding guidelines, swapping out this flop > can be done by tweaking the include path for the library, you would > have to visit every line of code in your design to see whether or not > the always block is actually a flop, and then recode by hand. ( Good if > you get paid by the hour, not so good for your employer ). >If you had coded in an always block, you don't have to anything at all! Any synthesis tool will figure out whether the cells have inverting inputs or not. Even if you accidentally put two inverters along the logic path, this will be optimized away from the truth tables constructed by the synthesis tools.> 3) Rebalancing logic across clock domain crossings is easier when the > logic is seperate from the flop : X's are flops (a,b,c) is assign wires > > X1 --> a --> b --> c --> X2 > X1 --> a --> b --> X2 --> c > > The only changes that need to occur, is the input from the X2 is > changed to be b, instead of c, and the input to c is changed to be the > output of X2 instead of the output of b. >Excuse me? Rebalancing across clock domains? It is never trivial and what you offered only works when you are balancing with the SAME clock domain.> Using "proper RTL", you might have coded "a,b,c" inside of an always > block. You then need to create more wires or modify an always blocks to > pull this logic out, and then hook it up. At the end, after you have > applied your timing fix, the code is larger. > > Worse yet, you may have made a mistake. These things tend to happen, > and when you recoded this flop, you have have left some path out, and > have turned it into a latch. These types of mistakes are not possible > to do in a instance -- assign -- assign -- instance methodology. > because "always @(posedge...)" is not allowed in your code, it belong > inside a library. >That's a lot of assumptions, not to mention many synthesis tools rebalance logic for you automatically.> Now you may say "But I am smarter than that!", well that is nice for > you. But when setting up a coding standard that needs to be used by > hundreds of engineers, and verified by tools, ad-hoc methods of "proper > RTL" get left in the dust behind rigid standards that prevent bad stuff > from happening in the first place. > > Please consider that this chip was probably design by a group of > engineers easily topping 100+, there were many compiler tools, > synthesis, and other tools that needed to manipulate this code, and get > meaningful information from it. Having each engineer write in what you > describe as "proper RTL" style is not acceptable in these situations. > It is not flexible enough ( you have to add lines of code just to make > timing fixes), error prone ( you can write logic that is not possible > or available in your library ), and doesn't get you *any* better > results. >I see the complete opposite. Having 100+ engineers working on the same project require them to actually understand each other's code quickly. A netlist style is NIGHTMARE. RTL is created to be different from netlist so that it is more readable.
Reply by ●March 28, 20062006-03-28
I think the main point you are missing of mine is that these techniques solve problems which it does not appear you are not familiar with. Adding another layer of indirection in the form of an instantiated flop model solves many of these problems and is an industry standard as far as high end retargetable ASIC coding standards are concerned. Each solution you have described involves adding more lines of code to the actual RTL source, and strips out any layers of indirection. It attaches implementation attributes directly to a design that is intentionally high level, so that it can be retargetd. Those layers of indirection are invisible to the tools that use them, synthesis, and simulator, but provide flexibility for the person who needs to model different behavior or change libraries. Now maybe you have not had the need to do this, in which case it seems superficial and a waste of time. But I can assure you, lots of time and effort was spent in building these components this way for a very good reason. -Art
Reply by ●March 28, 20062006-03-28
> Again, I don't see how writing always blocks is "unmaintainable." Maybe I haven't had enough experienceLet met explain then. Here is the "proper RTL" as some other might right it : wire [31:0] a ; wire [31:0] b ; reg [32:0] result ; always @(posedge clk) result <= a + b ; Here is what you will find in many high end synthesizable RTL coding standard examples : wire[31:0] a ; wire[31:0] b ; wire[32:0] a_plus_b ; assign a_plus_b = a + b ; my_dff #(33) a_plus_b_32_0 ( .out( result ), .clk(clk), .in(a_plus_b) ) ; My simple assertion is that the added layer of indirection provided by the "my_dff" construct, and the seperate wire containing the result, gives me things easily, that would require RTL changes in the above example. Lets say I want to simulate my design and initialize all registers to a non-X state, just for simulations, just to see what would happen. I would swap in a different my_dff with the attribute that I want, it would change my compile script, but not my source code. There are plenty of other transformations that I may want to do on the code. If you don't ever do transformations on your code, and it all fits in a FPGA that you can plug into your real system and test, then you don't need this coding style. But if you pay millions of dollars per churn of an ASIC, you want to be able to have the flexibility in your Simulation testbench. Now to your point that you think it is easier to read the first examples. My only response is, "sure because you are used to it". If you worked in high end retargetable ASIC designs you would be used to writing the other way, and it would be just as easy to read. -Art
Reply by ●March 29, 20062006-03-29
Art Stamness wrote:> Please provide any evidence of this assertion : > > " The price you pay is very large: unmaintainable, unreadable code > which is probably an order of magnitude larger than proper RTL." > > This coding style which you so clearly denegrate as sub par, is > actually quite standard among high end chip development.I fear you're right :-)> Some reasons :> .... From this and other posts I believe you mentioned the following tasks as arguments for the coding style in question: 1) randomization of flip-flop start-up values 2) retargeting a netlist to another technology 3) retiming for performance My feedback would be that we face a methodology problem. Proper RTL also means proper usage of available abstraction levels. RTL is effective for functional description and verification, but that's it. The task you describe can better be handled as follows: 1) gate level simulation 2) synthesis tool used in retargeting mode 3) advanced synthesis tool working at the gate level Trying to do such things manually and at the RTL level will naturally get you into trouble, to the point of generating self-fulfilling prophecies ...> Please consider that this chip was probably design by a group of > engineers easily topping 100+, there were many compiler tools, > synthesis, and other tools that needed to manipulate this code, and get > meaningful information from it. Having each engineer write in what you > describe as "proper RTL" style is not acceptable in these situations.There you have it ;-) Jan -- Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com Losbergenlaan 16, B-3010 Leuven, Belgium From Python to silicon: http://myhdl.jandecaluwe.com
Reply by ●March 29, 20062006-03-29
Art Stamness wrote:> Please provide any evidence of this assertion : > > " The price you pay is very large: unmaintainable, unreadable code > which is probably an order of magnitude larger than proper RTL."A proper comparision would be to undertake the same project twice, using the 2 design styles independently and then compare results. Typically unfeasible of course. However, in my previous life at the design service company I co-founded (Easics) I have had the occasional opportunity to compare. A good example is the following. In 1996, we had an industry-first implementation of a complete USB slave (PHY+HUB) (Philips was the customer.) At one point, Intel released a reference design of the PHY part and we compared. Their design was written in, let's say, OpenSPARC style, and had 30+ modules with low level, incomprehensible code. It synthesized to 4000+ gates. Ours had just 3 modules with clear RTL code and synthesized to around 2500 gates. Small design of course, but that is the trend. We have seen it confirmed on a few other comparison occasions, and there is every indication that things get only worse for larger designs. Jan -- Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com Losbergenlaan 16, B-3010 Leuven, Belgium From Python to silicon: http://myhdl.jandecaluwe.com
Reply by ●March 29, 20062006-03-29
Jan Decaluwe wrote:> Their design was written in, let's say, OpenSPARC style, and > had 30+ modules with low level, incomprehensible code. It > synthesized to 4000+ gates. Ours had just 3 modules with clear > RTL code and synthesized to around 2500 gates.Interesting story.> Small design of course, but that is the trend. We have seen > it confirmed on a few other comparison occasions, and there > is every indication that things get only worse for larger designs.Some organizations have huge monetary and cultural commitments to certain classical cae point tools that defy rational discussion. -- Mike Treseler
Reply by ●March 29, 20062006-03-29
Art Stamness wrote: <snip>> My simple assertion is that the added layer of indirection provided by > the "my_dff" construct, and the seperate wire containing the result, > gives me things easily, that would require RTL changes in the above > example. > > Lets say I want to simulate my design and initialize all registers to a > non-X state, just for simulations, just to see what would happen. I > would swap in a different my_dff with the attribute that I want, it > would change my compile script, but not my source code. >Yes, I agree with you that it is easy to do this particular transformation with your style. However, it's not enough to convince me, as this transformation can also be easily done with the proper RTL style, if not easier. With one or two lines of regular expression code/shell script, I can mine through the entire source code and generate a big initial block, which I conveniently insert in the testbench. To me, portability is greater with more abstraction in the code, because it gives synthesis tools greater freedom to implement the logic.






