FPGARelated.com
Forums

FPGA Market Entry Barriers

Started by Unknown October 18, 2018
gnuarm.deletethisbit@gmail.com wrote:
> I don't think that is the point. The verbosity of VHDL is intended. > There are things that you have to do in VHDL that aren't done in Verilog > where the intent is to avoid a class of mistakes. This is the reason for > strong typing which brings on some verbosity.
Types are good. But why do I have to write 'signal x : std_logic_vector(31 downto 0)' when I could just type 'logic [31:0] x' ?
> an_integer_variable <= to_integer(some_other_data_type); > > Sometimes the function to_integer() isn't defined for that "other" data > type and you have to write the conversion function or convert to an > intermediate type. The point is to not *assume* the compiler knows what > the user intended and to make it all explicit. Then a subsequent reader > can see exactly what was intended.
I agree completely. But you can be explicit without hurting your keyboard. Spend the keystrokes where it matters. (I'm fed up of reading through pages and pages of Verilog code that merely describes the interfaces to a component, which does a tiny amount of work and then instantiates another component that's almost the same inside it. When you get 8 levels down in this tree of input and output wires it gets very tiresome)
> It's not quite that bad. The tools support what the users request. So > the most often used features are supported in most tools.
So why is there a standard if tools can cherry pick what is and isn't supported? One of my colleagues has a table of what SystemVerilog features are supported across different tools. To have a multi-tool project, you end up with the lowest common denominator, at which point most of the useful features aren't an option.
> What about simulation? Is the BSV simulated or the Verilog?
BSV has its own simulator, which simulates at a higher level of abstraction so runs a lot faster than a Verilog simulator. You can, of course, simulate the verilog if you want to, but generally we find that code that simulates in the BSV simulator will work first time on FPGA. (The tricky bit is dealing with external IP like DRAMs - to get better testing coverage we have randomised models in BSV, rather than simulating the DRAM controller and DRAM IP in Modelsim)
> How do you distinguish code that is combinatorial?
function Bool i2xj( td i, td j ) provisos( Arith#(td), Eq#(td) ); return ( (i - 2*j) == 0 ); endfunction is a polymorphic combinatorial function that takes two inputs i and j. We don't know the type of i and j, but we do know that it must be the same, the type (we'll call it 'td') must support arithmetic and testing equality. If it doesn't, it's a compile error. So I couldn't use this for a string, for example. For any instantiation of this function, we'll accept the parameters i and j and generate logic that computes i-2j and compares it to zero, returning a boolean value. If I wanted to instantiate this in a module, I'd do something like: // define some registers with their types and default values Reg#(UInt#(64)) f <- mkReg(44); Reg#(UInt#(64)) g <- mkReg(22); Reg#(Int#(9)) p <- mkReg(-1); Reg#(Int#(9)) q <- mkReg(4); Reg#(Bool) m <- mkReg(False); Reg#(Bool) n <- mkReg(True); rule comparethem; // at the next clock cycle, set h to the combinatorial function of f and g m <= i2xj(f, g); // instantiate another copy of the function, this time with // different types n <= i2xj(p, q); endrule If you want your module to have purely combinational behaviour, there are 'Wire' types which act like registers but return the answer in the current clock cycle, not the next one (unlike Verilog, a Wire has the same syntax as a Reg, but different timing behaviour). The compiler will schedule logic so that things that depend on Wire outputs are downstream so that they are consumed when the wires have computed their results. Wires are commonly used to pass data between rules (which are the building block of BSV, each one being an atomic action with implicit conditions). Theo
gnuarm.deletethisbit@gmail.com wrote:
> Yeah, not so small though. The package is 22 mm square and my board is > only 21.6 mm wide! If I have to I can squeeze a BGA-256 on the board. I > just don't want to deal with the layout issues.
If it's an FPGA, I think you can get quite a way by just ignoring half of the balls. Provide power and ground, then just use the I/Os that are easy to get at and ground the rest. Depends what you need in terms of pins, but it makes the BGA escapes a lot easier if you only have to go a couple of rows deep. Obviously this doesn't work for chips where balls have a fixed function! Theo
On Saturday, October 27, 2018 at 6:41:44 PM UTC-4, Theo wrote:
> gnuarm.deletethisbit@gmail.com wrote: > > I don't think that is the point. The verbosity of VHDL is intended. > > There are things that you have to do in VHDL that aren't done in Verilog > > where the intent is to avoid a class of mistakes. This is the reason for > > strong typing which brings on some verbosity. > > Types are good. But why do I have to write > 'signal x : std_logic_vector(31 downto 0)' when I could just type > 'logic [31:0] x' ?
I see you are not very familiar with VHDL strong typing. In your example, what type is x? What sort of values can be assigned to it? What type of math is used when it is added to the same type?
> > an_integer_variable <= to_integer(some_other_data_type); > > > > Sometimes the function to_integer() isn't defined for that "other" data > > type and you have to write the conversion function or convert to an > > intermediate type. The point is to not *assume* the compiler knows what > > the user intended and to make it all explicit. Then a subsequent reader > > can see exactly what was intended. > > I agree completely. But you can be explicit without hurting your keyboard. > Spend the keystrokes where it matters. > > (I'm fed up of reading through pages and pages of Verilog code that merely > describes the interfaces to a component, which does a tiny amount of work and > then instantiates another component that's almost the same inside it. When > you get 8 levels down in this tree of input and output wires it gets very > tiresome) > > > It's not quite that bad. The tools support what the users request. So > > the most often used features are supported in most tools. > > So why is there a standard if tools can cherry pick what is and isn't > supported? One of my colleagues has a table of what SystemVerilog features > are supported across different tools. To have a multi-tool project, you end > up with the lowest common denominator, at which point most of the useful > features aren't an option.
Yep. Vendors give users what they ask for. If you are a paying customer you should inquire about any feature you feel should be included. If you aren't a paying customer, I guess you have no say.
> > What about simulation? Is the BSV simulated or the Verilog? > > BSV has its own simulator, which simulates at a higher level of abstraction > so runs a lot faster than a Verilog simulator. You can, of course, simulate > the verilog if you want to, but generally we find that code that simulates > in the BSV simulator will work first time on FPGA.
I guess you are stuck with the one vendor then, although I shouldn't use a loaded word like "stuck". Rick C.
On Saturday, October 27, 2018 at 7:02:56 PM UTC-4, Theo wrote:
> gnuarm.deletethisbit@gmail.com wrote: > > Yeah, not so small though. The package is 22 mm square and my board is > > only 21.6 mm wide! If I have to I can squeeze a BGA-256 on the board. I > > just don't want to deal with the layout issues. > > If it's an FPGA, I think you can get quite a way by just ignoring half of > the balls. Provide power and ground, then just use the I/Os that are easy to > get at and ground the rest. > > Depends what you need in terms of pins, but it makes the BGA escapes a lot > easier if you only have to go a couple of rows deep. > > Obviously this doesn't work for chips where balls have a fixed function!
You mean like power and ground? I recall one type of BGA that has concentric rings of I/Os with a large open area in the center. Easy to route but I don't see those anymore. It is common to put power and ground near the center as it results in shorter, lower inductance paths inside the chip package. So those pretty much always need vias between the pads. Rick C.
gnuarm.deletethisbit@gmail.com wrote:
> On Saturday, October 27, 2018 at 6:41:44 PM UTC-4, Theo wrote: > > Types are good. But why do I have to write > > 'signal x : std_logic_vector(31 downto 0)' when I could just type > > 'logic [31:0] x' ? > > I see you are not very familiar with VHDL strong typing. > > In your example, what type is x? What sort of values can be assigned to > it? What type of math is used when it is added to the same type?
So if I was writing in a strongly typed language rather than a disaster like Verilog, it would be: Reg#(UInt#(32)) - still a lot fewer keystrokes. UInt supports Bits (can be converter to a bit vector), Eq (can be equality tested), Arith (arithmetic operations), and so on. The behaviour when combining two values of the same or different types are defined, and I can overload them if I really want to (but I probably don't). Theo
On Sunday, October 28, 2018 at 7:51:11 AM UTC-4, Theo wrote:
> gnuarm.deletethisbit@gmail.com wrote: > > On Saturday, October 27, 2018 at 6:41:44 PM UTC-4, Theo wrote: > > > Types are good. But why do I have to write > > > 'signal x : std_logic_vector(31 downto 0)' when I could just type > > > 'logic [31:0] x' ? > > > > I see you are not very familiar with VHDL strong typing. > > > > In your example, what type is x? What sort of values can be assigned to > > it? What type of math is used when it is added to the same type? > > So if I was writing in a strongly typed language rather than a disaster like > Verilog, it would be: > > Reg#(UInt#(32)) > > - still a lot fewer keystrokes. > > UInt supports Bits (can be converter to a bit vector), Eq (can be equality > tested), Arith (arithmetic operations), and so on. The behaviour when > combining two values of the same or different types are defined, and I can > overload them if I really want to (but I probably don't).
I'm still not clear on the syntax. Is Reg the signal name? What types are there other than UInt which I assume is an unsigned integer? Verilog has always confused me with reg and wire (I think). I've never understood what the difference was. That's mostly because I've never bought a good book on it and that's because every time I ask I'm told there are *no* good books, lol. Rick C.
On 27/10/2018 22:57, Theo wrote:
> HT-Lab <hans64@htminuslab.com> wrote:
..
>> I haven't spend much time looking into Bluespec but I do know that many >> companies are nervous adopting a custom language supported by a single >> vendor. > > Yes, this is a big problem. It's something Bluespec Inc themselves realise > too - I think they would open source the compiler but they have customers > who are paying the bills, so... > > (There are also other toy BSV compilers around, but nothing I've seen that's > production ready)
At least there is enough information available in the public domain to write a toy BSV compiler, that is good news (patents issues aside). I assume Bluespec has a healthy customer list so assuming they sell perpetual licenses I guess the plunge is not that big.
> > However it's slightly different from the VHDL/Verilog problem. The > VHDL/Verilog tools are compiling to something else (standard cells, FPGA > netlists). If you're targeting Altera, you have to use Quartus for this. If > you want to move your code to an ASIC, you now have to switch to Synopsys DC > (or whatever), and discover that your SystemVerilog constructs aren't > supported. In the BSV case, the Verilog 95 emitted by the BSV compiler can > be used with Altera or Synopsys. So your backend is flexible, even > if one piece of your frontend is fixed.
OK, I will give you that one. As we all know switching between vendors always requires work.
> >> Impressive example, however, I am not sure if any other high level RTL >> language will be a lot more verbose. You are instantiating a FIFO and >> connecting the ports with a bit of control logic right? > > In that noddy example. Interfaces mean you can wrap up a lot of verbosity > into a few lines. For a randomly selected example, here's a processor TLB, > in 500 lines of BSV: > https://github.com/CTSRD-CHERI/beri/blob/master/cheri/trunk/TLB.bsv >
The code looks very tidy but of course I can't compare it to any other implementation. I have written my own TLB (for a 486) and it is about 900 lines of VHDL but again no way to compare them. From your examples I can see BSV is a lot more verbose and expressive at the same time, I guess that is the advantage of a modern language well though out language.
> Also, being polymorphic, you can generate a variety of different modules from > the one description - which saves a lot of repetition. > >> It looks like BSV sits between RTL and HLS, you have raised the level of >> abstraction but still have an implicit clock. > > Yes. It's still timed, so you still have decide what's going in each cycle. > (or at least your idea of that - your synthesis tool may retime). And it's > possible to get bubbles - your system still works, but takes more cycles > because parts will stall if there's no data for them to operate on.
That is interesting as we are no longer talking about a more modern expressive language which has a user understandable mapping to hardware but actually something that implements flow control as well. This is quite nice but a bit worrying as it makes the debugging from your Verilog95 back to BSV a lot more complex. This is one aspect that is always playing in the HLS world, how do you guarantee your untimed C/C++ code is equivalent to the produced RTL. Calypto can do this but I am sure this is outside the EDA budget for most of us. If I find a critical path during synthesis, how easy is this to link back to the BSV code?
> Also, there's still skill in understanding what will impact your critical > path. > > ISTM one issue with HLS is it's good at handling work in the datapath, but > perhaps not so good in the control path. So you can describe some kinds of > compute very well, but I'm not sure how well they would handle a > control-heavy structure like a cache.
You are absolutely right, for the control logic they always suggest to either use one of the RTL languages or SystemC (which has similar constructs to VHDL/Verilog). Thanks for the BSV examples, quite interesting. Hans www.ht-lab.com
> > Theo >
gnuarm.deletethisbit@gmail.com wrote:
> On Sunday, October 28, 2018 at 7:51:11 AM UTC-4, Theo wrote: > > So if I was writing in a strongly typed language rather than a disaster > > like Verilog, it would be: > > > > Reg#(UInt#(32)) > > > > - still a lot fewer keystrokes. > > > > UInt supports Bits (can be converter to a bit vector), Eq (can be equality > > tested), Arith (arithmetic operations), and so on. The behaviour when > > combining two values of the same or different types are defined, and I can > > overload them if I really want to (but I probably don't). > > I'm still not clear on the syntax. Is Reg the signal name? What types > are there other than UInt which I assume is an unsigned integer?
Reg is the typeclass of the hardware being built, which is parameterised (# symbol) on type UInt (unsigned int), which is itself parameterised with the number 32. In other words, we're defining a register (a general purpose thing that can hold a variety of things) specifically to hold UInts, and those UInts happen to be 32 bits long. Other basic types are Bits (a pile of bits), Int (signed integers that can be converted to piles of bits), Bool (boolean - True or False), Integer (integers that aren't bits, often used for polymorphism - the '32' in the above is an Integer), Real numbers (without a direct representation as bits - if you want that you have to write conversion functions), Strings, and so on. There are also things like Maybe types, which can either hold a value (of a type you specify) or Invalid (meaning this container does not hold a value). There's nothing special about any of these typeclasses - you can build your own if you want. If you're instantiating a register you need to give it an implementation, so a register called 'bob' would be: Reg#(UInt#(32)) bob <- mkReg(99); 'mkReg' is a particular implementation of the Reg typeclass (there are others), and 99 is a parameter to mkReg (in this case, the value on reset).
> Verilog has always confused me with reg and wire (I think). I've never > understood what the difference was. That's mostly because I've never > bought a good book on it and that's because every time I ask I'm told > there are *no* good books, lol.
In Verilog, AIUI there is no difference - that's why SystemVerilog has 'logic' to avoid people thinking there is. It purely depends on how they get used, which makes more sense when you consider Verilog's origins as an event simulation language. The difference between: always @(posedge s or negedge s) a <= s+2; assign a = s+2; is that the 'always @(posedge s or negedge s)' will update a on 'any edge of s' [1], and 'assign' will update a on of 'any edge of s and the start of the simulation'. The latter boils down to a combinational function, the former is a stateful element - holding a value until the first edge of 's', or some other condition like @(posedge clock). Once you stop thinking about digital logic and think about arbitrary events it makes more sense. Theo [1] technically, to write that would need always @(s) because there are other kinds of edges beyond posedge or negedge, like edges to Z, X, etc. @(s) means 'any transition on signal s'.
On 28/10/2018 13:00, gnuarm.deletethisbit@gmail.com wrote:
> On Sunday, October 28, 2018 at 7:51:11 AM UTC-4, Theo wrote:
..
> > I'm still not clear on the syntax. Is Reg the signal name? What types are there other than UInt which I assume is an unsigned integer? > > Verilog has always confused me with reg and wire (I think). I've never understood what the difference was.
SystemVerilog cleaned up the language significantly, instead of reg and wire you can now use the logic type. Unfortunately SystemVerilog is build on top of (the in 1984 developed) Verilog so you still have to deal with all the blocking and non-blocking nonsense. SystemC and VHDL users are lucky in that they only have to deal with the odd delta cycle issue. I guess there are no delta cycle issues in BSV.
> That's mostly because I've never bought a good book on it and that's because every time I ask I'm told there are *no* good books, lol.
My company send me on a Doulos Verilog course many years ago. Doulos courses are not cheap but they are very very good. But even with a good course you still have to practice, practice and when you have a spare second practise. If you leave the language for a few years you have to start from scratch again unless you are below 30. Given that most simulators are now dual language you can write small blocks in SV and use that with your VHDL code. I did the same for SystemC. Hans www.ht-lab.com
> > Rick C. >
HT-Lab <hans64@htminuslab.com> wrote:
> On 27/10/2018 22:57, Theo wrote: > That is interesting as we are no longer talking about a more modern > expressive language which has a user understandable mapping to hardware > but actually something that implements flow control as well. This is > quite nice but a bit worrying as it makes the debugging from your > Verilog95 back to BSV a lot more complex. This is one aspect that is > always playing in the HLS world, how do you guarantee your untimed C/C++ > code is equivalent to the produced RTL. Calypto can do this but I am > sure this is outside the EDA budget for most of us. > > If I find a critical path during synthesis, how easy is this to link > back to the BSV code?
BSV preserves names from the target code into its generated Verilog, which is reasonably understandable if not particularly editable. It looks like a big pile of always @(posedge clock) nextstate <= combinational_fn( previousstate ) which tools handle just fine. The name preservation means that debugging it using Verilog tools like SignalTap/Chipscope is feasible and, if you know what the BSV was supposed to be doing you can generally follow that through to the Verilog. Similarly, the name in the synthesis tool can be tracked back to the BSV (though obviously, don't expect the combinational logic at that stage to look the same as the combinational logic in your source). You do need to understand a bit what's going on - if you make an enormous mux then it'll be slow, and since it makes it easier to write things you can also write enormous slow things if you aren't paying attention. (I once wrote the whole of SHA256 as a single-cycle combinational function, which took about a dozen lines of BSV. It crashed Quartus ;-) There aren't any tools to my knowledge that check equivalence between the BSV source and the RTL, but then that's a bit like checking equivalence between your C++ source code and your assembly output - if it fails, it's a compiler bug. Theo