FPGAwars / icestudio

:snowflake: Visual editor for open FPGA boards
https://icestudio.io
GNU General Public License v2.0
1.69k stars 244 forks source link

signed arithmetic collections? control code block collections? #509

Open SiccoDwars opened 3 years ago

SiccoDwars commented 3 years ago

Started using Icestudio for logic interfacing and legacy protocols, great tool, many thanks. But now keen to take things to a next level and that is to let the ICE40 FPGA do some feedback control. Signals of 16 bits, signed ints, 2-complement. For that I need:

What I had hoped for is that someone already went trough the effort of writing such a toolbox / library / Collection of straight forward integer arithmetic blocks.

So far I only found "unsigned" arithmetic bits and pieces here and there in Collections on github. And lots of Verilog modules from way before the Icestudio era. My struggle is to convert those into reliable, robust, proven, already debugged versions of Icestudio blocks that I can import. Am I looking in the wrong place? Used to have these type of libraries with visual drag and drop capability in e.g. LabView FPGA, or in CodeSys, or in ABB DriveAP, Siemens DCC or in IEC61131.

My struggles with Icestudio are on how to decently declare Icestudio Verilog code blocks that have by default 16 bits signed inputs and outputs. With decent saturation against maxint and minint. Is starting to rewrite from scratch all by myself really the only way forward here?

SiccoDwars commented 3 years ago

Somewhat related: has anyone managed to write re-useable soft IP 'code blocks' for the ICE40UP on board hardware SPI and I2C ports in its 4 corners? And how about pre-cooked re-useable examples for the on board RAM? The PLL examples (cut and paste verilog code into an Icestudio code block) worked for me. So my hope is someone already did something similar for the other Lattice ICE40 specific hardware and its many SB_xxx registers.

TimRudy commented 3 years ago

For arithmetic, compare, min and max, I see what you're saying and this collection github.com/TimRudy/ice-chips-verilog was created to make general code available and it is tested/trusted. Each block can be 16 bit or 32 bit or any value. See, the code itself does not have to be inside a specific hardware device like a 74x283 adder.

Problem 1: The multiplier is not implemented (ex. 74x274, 74x284, 74x285 - or higher device numbers, whatever is easy to use, say not having a serial interface); Problem 2: Nor is a divider implemented, and I have no idea how easy-to-use or useful a divider would be (ex. multiplier/divider 74x508, it is quite specialized, acts in a programmed way and uses a clock)

Do you agree there is some synergy yet some mismatch between your goals of plug-and-play arithmetic, and the ice-chips-verilog goals of specific hardware + general code? The synergy is that it seems there should be general code that does these jobs on n bits, and I would like to host that code; the mismatch is that code targeted to an FPGA can be as wide and big as needed, doing a multiply in a convenient combinatorial way as if it was an add; and I guess that is what you would like; there is no "legacy chip" for that; but the mismatch can be overcome because I would love to host a second collection that would be branded as "arithmetic" rather than "7400". It would make sense, right?

SiccoDwars commented 3 years ago

Many thanks Tim. The good old 7400 TTL days - sweet memories… Maybe one day also convert your Verilog modules into Icestudio collections so that they’re readily available from the Icestudio precooked pulldown menus… And then we rebuild the digital wall clocks and frequency counters like we used to do 40 years ago! And an Apple ][ motherboard in one chip…

Back to my original request, I think there is plenty of Verilog www example code, like http://120.107.171.121/~tywua/sub/PROTOTYPE/Signed_Arithmetic.pdf or https://excamera.com/sphinx/fpga-verilog-sign.html or even fixed point arithmetic like https://github.com/freecores/verilog_fixed_point_math_library. The hurdle that I am facing is how to wrap those Verilog modules into Icestudio code blocks. I’d assume that Icestudio can do + and - and * and <<< and >>> and <, >, = as coded in Verilog code, but how to ensure that code inside an Icestudio code block appreciates that when operands on say a 16 bits input are signed rather than unsigned, that code behavior and output property shall be different? How to specify that input and output are signed ints, not unsigned?

Happy to start drafting the aspired Collection, but need some help to get going. Grateful for anyone drafting an example of Icestudio code blocks for 2-complement basic arithmetic, so just the add, sub, mul for say just 4 bit operands.

Sent from my iPad2

On Jun 27, 2021, at 2:32 AM, TimRudy @.***> wrote:

 For arithmetic, compare, min and max, I see what you're saying and this collection github.com/TimRudy/ice-chips-verilog was created to make general code available and it is tested/trusted. Each block can be 16 bit or 32 bit or any value. See, the code itself does not have to be inside a specific hardware device like a 74x283 adder.

Problem 1: The multiplier is not implemented (ex. 74x274, 74x284, 74x285 - or higher device numbers, whatever is easy to use, say not having a serial interface); Problem 2: Nor is a divider implemented, and I have no idea how easy-to-use or useful a divider would be (ex. multiplier/divider 74x508, it is quite specialized, acts in a programmed way and uses a clock)

Do you agree there is some synergy yet some mismatch between your goals of plug-and-play arithmetic, and the ice-chips-verilog goals of specific hardware + general code? The synergy is that it seems there should be general code that does these jobs on n bits, and I would like to host that code; the mismatch is that code targeted to an FPGA can be as wide and big as needed, doing a multiply in a convenient combinatorial way as if it was an add; and I guess that is what you would like; there is no "legacy chip" for that; but the mismatch can be overcome because I would love to host a second collection that would be branded as "arithmetic" rather than "7400". It would make sense, right?

If you wish, open this issue on the ice-chips-verilog library and we can discuss what's the best value-for-money. (It will be free, by the way - but someone will have to write or purloin the code.) There has been discussion of fixed-point division by @Democrito, and there may be some relation to this discussion, see https://groups.google.com/g/fpga-wars-explorando-el-lado-libre/c/Is2UsxOY4Bk/m/Lvta_VIfAAAJ — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

TimRudy commented 3 years ago

It will be up to the user of the Verilog code block to say whether the block is doing signed or unsigned (*let's start with an adder/subtractor), as numbers are just in the eye of the beholder: When you use 2's-complement, "Signed and unsigned numbers can use identical circuit".

I have an .ice module for you (just have to push it somewhere). So in fact this .ice adder can do unsigned add, signed add, and subtract of two signed or unsigned numbers (you'll see in test bench code, subtract is same as add).

I made test benches that show the 2 different interpretations of the numbers. These two are signed:

  // -9 + -3 + Carry 0 -> -12 + Carry 1 (???semantic meaning to be explained???) == -12
  A = 5'b10111;
  B = 5'b11101;
  C_in = 1'b0;
#6
  tbassert(Sum == 5'b10100, "Test 6");
  tbassert(C_out == 1'b1, "Test 6");

  // 1 + -16 + Carry 0 -> -15 + Carry 0 == -15
  A = 5'b00001;
  B = 5'b10000;
  C_in = 1'b0;
#6
  tbassert(Sum == 5'b10001, "Test 7");
  tbassert(C_out == 1'b0, "Test 7");

Exact same tests (see same binary) for unsigned:

  // 23 + 29 + Carry 0 -> 52
  A = 5'b10111;
  B = 5'b11101;
  C_in = 1'b0;
#6
  tbassert(Sum == 5'b10100, "Test 6");
  tbassert(C_out == 1'b1, "Test 6");

  // 1 + 16 + Carry 0 -> 17 + Carry 0 == 17
  A = 5'b00001;
  B = 5'b10000;
  C_in = 1'b0;
#6
  tbassert(Sum == 5'b10001, "Test 7");
  tbassert(C_out == 1'b0, "Test 7");

The adder implementation can be improved, and one example would be another output:

Overflow: The result of arithmetic operations should fit in the bits available for output. If the result of an arithmetic operation doesn’t fit into the bits provided, then an arithmetic overflow occurs. Overflow can be detected by comparing the carry-in and carry-out of the sign bit in the numbers

To discuss saturation, it seems to mean chopping off the high-order bits of numbers that exceed your 16-bit circuitry (chop off and leave a 1 in high bit if it is max (-), leave a 0 in high bit if it is max (+). A block external to this adder can do that with straightforward Verilog, i.e. it would be in a context of a 32-bit path, say, and in that context you'll be aware of what you want to do with arithmetic; so you pass your chopped 16-bit numbers to this adder. How is that?

TimRudy commented 3 years ago

The adder16.ice is at https://github.com/TimRudy/ice-chips-verilog/tree/Arithmetic/source-arithmetic, for you to play with

SiccoDwars commented 3 years ago

Hi Tim, thanks, I’ll have a play over the weekend.

On previous message and can one reuse unsigned arithmetic as-is for signed 2-complement: while it may work for add and subtract of equal bit length operands, it will fail for functions like min, max, <, >. Also when the add function is to use saturation or decent carry in, carry out, things must work differently.

As in -2 is less than +1, but the binary 2-complement representations are not.

Or as in -1 + 3 is 2, without overflow, irrespective of saturation being enabled. But 8 bits 126 + 4 with saturation enabled should give 127.

When adding different bit length operands, say add a 24 bit signed number plus a 16 bits signed number, the 16 bit number needs to be inflated to 24 bits, but not by simply adding 8 zero bits in front because then negative numbers fail.

Sent from my iPad2

On Jul 2, 2021, at 6:53 AM, TimRudy @.***> wrote:

 The adder16.ice is at https://github.com/TimRudy/ice-chips-verilog/tree/Arithmetic/source-arithmetic, for you to play with

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

TimRudy commented 3 years ago

OK, as next step I put up 2 different comparators comparator16-unsigned.ice, comparator16-signed.ice

Run test benches with: iverilog -g2012 -ocomparator-tb.vvp ..\includes\tbhelper.v comparator-signed-tb.v comparator-signed.v

For me test benches are what we need; any specs that can be specified can be implemented

SiccoDwars commented 3 years ago

I’ve progressed things to this now: https://github.com/SiccoDwars/Icestudio-ArithmeticBlocks Was a lot more work as expected of course, and it’s not quite yet what I am still aiming for. Not everything is tested yet.

image

SiccoDwars commented 3 years ago

An Icestudio Collection for these integer mathematics Verilog blocks - now made it myself. Here it is if anyone else interested. int_math_Collection_sd.zip

(suggestion to the makers of the icm tool: would be great if the tool 'icm update' delivers also the final zipped collection as a .zip file. I've wasted a day battling two painful issues:

  1. Apparently the zip file must be made with a linux zip, not a Windows zip tool. When zipping in Windows, the zip file gets rejected in Icestudio tools-collection-add, without any notice...
  2. The file structure in the zip must start with a root file that only has one folder, and that folder has the other files and subdirectories. Zipping just the folder so that e.g. package.json and readme etc end up in the root of the zip is apparently not allowed...)
Obijuan commented 3 years ago

Thanks for your contribution!
For creating a collection you should create a repository with a special folder structure. You can check other collections to see this structure. For example, take a look at the icegate collection

Once you have that structure, you just get the .zip file from github directly: click on the Code buton (the green button localted on the top right) and then Download as Zip

You can create the structure from scratch using the icm create command

I will do a pull-request to the https://github.com/SiccoDwars/Icestudio-ArithmeticBlocks repository for you as an example. Then you can reorganize the blocks in menus and submenues as you like

Obijuan commented 3 years ago

Pull request created! https://github.com/SiccoDwars/Icestudio-ArithmeticBlocks/pull/1

The Readme file is automatically generated from the package.json file (with the icm update command)

SiccoDwars commented 3 years ago

OK thanks. So what you're suggesting is that creating a Collection zip must be done through/by Github, with the act of zipping performed by GitHub servers instead of locally on the machine that I am using? What I was assuming is that it would be possible to do it all 'off-line', locally on my PC. As in I have on my PC a folder full of .ice files, nicely structured with subfolders, and then a tool like icm simply and flawlessly pushes that folder full of great new blocks into just the one zip file that Icestudio imports flawlessly. So with the act of zipping done by the same tool on the same PC. Which apparently is possible, manually adding the zipping step, with Linux Python zip under WSL/Ubuntu, but NOT if I use Windows zip after I did 'icm update' in WSL/Ubuntu/Python. The zip file made by Windows (Win11) produces a slightly different zip file and with that the Collection import in Icestudio simply fails - without further notice. Attached two example zip Collection files, one works because created in Linux, the other does not because the zip file was created in/with Windows.. int_math_Collection_sd (2).zip int_math_Collection_sd.zip .

Obijuan commented 3 years ago

Yes you are totally right. The collection can be created locally by zipping the folder as long as it has the correct structure. I agree that it would be great to include it in the icm tool, so that it works ok in any operating system. It has not been implemented yet (but it is a great suggestion). In the meantime, if the collection is stored in the github repo with the correct structure it is rather easy to create the .zip for any user to download and test it.

So, I will leave this issue opened until this feature is implemented. For example the argument package can be added, so that if you type the command icm package, the .zip is generated (independly of the operating system)

Thank you very much for you feedback

SiccoDwars commented 3 years ago

That would be great. For a next version of icm. But still I think it would also be good if Icestudio gives the user more feedback if a 'Collection zip' doesn't meet its expectation. Icestudio just staying silent without telling the user that (and why!) a collection zip got rejected just doesn't feel right. I struggled with two independent reasons why the zip didn't get through: a) incompatibility in Windows versus Linux zipping methods and b) a mishap in not having a root folder in the zip right above the readme and package.json etc. Thanks for the tool, the progress and the prompt follow-up!

Democrito commented 3 years ago

It would be very good to include the SiccoDwars library in the "Jedi" collection, "Arithmetic" section. It's just a suggestion. The "Jedi" collection is the most complete and it is about everyone doing their bit.

Greetings and thanks for the good work you have done SiccoDwars.

SiccoDwars commented 2 years ago

Somewhere higher up in this thread I asked if anyone had been successful writing ICE40 code in Icestudio for the SPI HW. And other code interfacing to ICE40 SB hardware like I2C, PLL, I/O, PWM, RAM etc. That's e.g. SPI using the chip's on-board hardware. Aka SPI Hardened IP. I now finally have something like that working for SB_SPI and SB_RAM40_4K but it was not easy. Painful as many relevant pieces of Lattice documentation are either missing or erratic (they assume we use their licensed tools with Module Generators...). Sharing my Icestudio example here. And asking the question: where to share this in a more decent structured way so that others will find it if they need it?

The code shared here is for ICE40UP5K. I'm using ICE40 Breakout Board and Icebreaker. This example implements a SPI slave. It has two SBRAM buffers of 256 words each. One is for 16 bits word data that is to be transmitted out over SPI from this slave, the other is for 16 bits word data that is received over SPI from its master. The SPI slave understands a few opcodes. Things like reading a version string, echo back data inverted, set a read and or write address pointer, and finally the most relevant things: read, read/write or write transactions where 1..N-1 words get im/exported. Note there is a snag with the HW SPI: following reception of say an opcode as first byte, it cannot simply send out 'fresh' byte data related to that opcode until an extra 8 SPI clocks have ticked. Therefore the data read over SO lags one extra byte relative to the date received over SI. So 2 bytes lag in total. Only tested for the first SPI port in a ICE40UP5K. To make it work for the seconds one, there's nitty gritty to sort out with BUS_ADDR74 and SPI_ADDR definitions.

One more thing in relation to Icestudio: the precooked Icebreaker and ICE40UP5K Breakout Board definition files I had to edit in order to enable the change in I/O direction for the SCL, MISO, MOSI, SS signals (this is the ICE40 as SPI slave, not as a master accessing things like external boot flash etc.) while still using the on-board FTDI chip initially. So I edited the pinout.pcf end the pinout.json files as per the 2nd zip attachment. They however reside in the /program files folders in Windows machine and will be overwritten whenever updating to a new Icestudio version. Can that be improved?

SBSPI Hardware SPI_16.zip pinouts.zip

Democrito commented 2 years ago

Hi SiccoDwars, I can only answer this question:

Sharing my Icestudio example here. And asking the question: where to share this in a more decent structured way so that others will find it if they need it?

At the moment there is no official place as a general library. Each collaborator has created a library and in some cases we collaborate on those collections. It remains to create a general library where we can find any type of module for Icestudio. And in order not to lose interesting and important things, what we are doing is writing a link to the Icestudio modules in a spreadsheet. This requires that you have what you want to share on GitHub and copy and paste the link into the aforementioned spreadsheet. This is the link:

https://docs.google.com/spreadsheets/d/1AHKN015UBKr_EUMdBTnh8m93segdq5jyYwSP5YSIi40

Thanks and greetings.