Shop OBEX P1 Docs P2 Docs Learn Events
P1v on the Upduino — Parallax Forums

P1v on the Upduino

I'm moving this discussion from the "Who Will be Prop2's Biggest Competition?" thread since it's way off topic for that thread. My current status is:

I have purchased a Upduino FPGA board
I have purchased an AdaFruit FT232H board to program the Upduino
I have installed the IceStorm toolchain on my Mac mini
I have succeeded in getting the up5k_rgb demo program running on my Upduino after some difficulty getting the RGB LED soldered in place

FYI, to use the AdaFruit FT232H board to load the Upduino wired as the documentation describes requires this command:
iceprog -d i:0x403:0x6014 rgb.bin
There are two things to note about this command line. First, it leaves out the "-S" option which is specified in the up5k_rgb Makefile. The "-S" option tells iceprog to write to the internal SRAM of the FPGA. The instructions for wiring the Upduino to the FT232H board describe setting it up for using an external flash chip for configuring the FPGA. Leaving out the "-S" option defaults to writing to the external flash.

Second, the "-d i:0x403:0x6014" option is required to address the AdaFruit board. It uses a different product ID than the board that iceprog assumes.

I'm going to try working with the P1v source code next. I'd like to get a single COG working with no hub memory to start. The entire 8 COG configuration will almost certainly not fit.
«1

Comments

  • jmgjmg Posts: 15,144
    David Betz wrote: »
    I have succeeded in getting the up5k_rgb demo program running on my Upduino after some difficulty getting the RGB LED soldered in place

    Great something is working....
    David Betz wrote: »
    FYI, to use the AdaFruit FT232H board to load the Upduino wired as the documentation describes requires this command:
    iceprog -d i:0x403:0x6014 rgb.bin
    
    There are two things to note about this command line. First, it leaves out the "-S" option which is specified in the up5k_rgb Makefile. The "-S" option tells iceprog to write to the internal SRAM of the FPGA. The instructions for wiring the Upduino to the FT232H board describe setting it up for using an external flash chip for configuring the FPGA. Leaving out the "-S" option defaults to writing to the external flash.
    useful info, but I'm curious why SRAM does not work, - most eval boards I've used can do both FLASH & SRAM ?
    Is there a PCB change to support SRAM loading, and the Upduino is wired so as to only FLASH boot.
    I guess flash has plenty of endurance, and it's probably better to test using the eventual actual boot path...

    How long does program take ?
  • You can program the SRAM by removing a jumper and swapping MISO and MOSI. I just tried it and it works fine. I was just trying to program it the way their instructions describe. Programming is very fast but this is a very simple example.
  • Heater.Heater. Posts: 21,230
    For those wondering what all this is about:

    The Upduino board is an very small, cheap Maker friendly FPGA board holding a Lattice Lattice iCE40 UltraPlus FPGA.
    http://www.latticesemi.com/en/Products/DevelopmentBoardsAndKits/GnarlyGreyUPDuinoBoard.aspx
    http://gnarlygrey.atspace.cc/development-platform.html#upduino

    Apart from being perhaps the smallest, cheapest FPGA board on the market the Upduino is very interesting because it can be configured using purely Free and Open Source tools. No more dependence on stupid vendor tools.

    IceStorm is the Open Source tool chain that can be used to go from Verilog to FPGA bitstream for the Lattice ICE FPGA's. An amazing feat of reverse engineering the FPGA bit stream and creating the required place and route and synthesis tools.
    http://www.clifford.at/icestorm/

    Despite being tiny the ULTA PLUS FPGA has 5.3K LUTs, 1Mb SPRAM, 120Kb DPRAM, 8 Multipliers. Quite enough for a soft core processor like the RISC V or perhaps the Propeller 1v. It has enough RAM on chip to be useful.





  • Heater. wrote: »
    For those wondering what all this is about:

    The Upduino board is an very small, cheap Maker friendly FPGA board holding a Lattice Lattice iCE40 UltraPlus FPGA.
    http://www.latticesemi.com/en/Products/DevelopmentBoardsAndKits/GnarlyGreyUPDuinoBoard.aspx
    http://gnarlygrey.atspace.cc/development-platform.html#upduino

    Apart from being perhaps the smallest, cheapest FPGA board on the market the Upduino is very interesting because it can be configured using purely Free and Open Source tools. No more dependence on stupid vendor tools.

    IceStorm is the Open Source tool chain that can be used to go from Verilog to FPGA bitstream for the Lattice ICE FPGA's. An amazing feat of reverse engineering the FPGA bit stream and creating the required place and route and synthesis tools.
    http://www.clifford.at/icestorm/

    Despite being tiny the ULTA PLUS FPGA has 5.3K LUTs, 1Mb SPRAM, 120Kb DPRAM, 8 Multipliers. Quite enough for a soft core processor like the RISC V or perhaps the Propeller 1v. It has enough RAM on chip to be useful.





    Thanks for the links. To program the Upduino I purchased this from AdaFruit. This is mentioned in the Upduino documentation.

    https://www.adafruit.com/product/2264
  • Heater.Heater. Posts: 21,230
    jmg,

    If I understand the Upduino schematics there are some shunts that can select programming RAM or FLASH:

    http://gnarlygrey.atspace.cc/downloads/UPDUINO_SCH_v1_0.pdf

    Looks like it requires soldering....
  • Heater: Have you tried compiling P1v with the IceStorm tools?
  • Right off the bat I'm running into this error:
    ERROR: Parser error in line cog_ram.v:39: syntax error, unexpected '[', expecting TOK_ID
    
    The offending line from cog_ram.v is:
    reg [511:0] [31:0]  r;
    
    Is this non-standard Verilog syntax?
  • Heater.Heater. Posts: 21,230
    edited 2018-01-15 02:48
    No. I have not tried building P1V for ages. Then under Quartus, When I find time....

    That's odd. Looks like the wrong syntax to me. But it's half a year since i have looked at any verilog so I forget exactly. But I notice Clifford Wolf defines his picorv32 CPU registers like so:
    reg [31:0] cpuregs [0:regfile_size-1];
    
    Which makes the P1 regs statement look like a syntax error.

    As does this explanation of Verilog arrays:
    http://www.verilogpro.com/verilog-arrays-plain-simple/

    Or this one:
    http://pages.cs.wisc.edu/~david/courses/cs552/S12/handouts/verilog2.pdf

    But how could there be such a syntax error in the P1V source now?

  • I'm not sure. I fixed all of those by changing things like:
    reg [511:0] [31:0]  r;
    
    to:
    reg [511:0]  r[31:0];
    
    However, I'm now getting this error:
    ERROR: Invalid array access at cog_alu.v:58.
    
    The offending line is:
    wire [7:0] ri[30:0] = { 31'b0,              // rev
                            {31{d[31]}},        // sar
                            {31{ci}},           // rcl
                            {31{ci}},           // rcr
                            31'b0,              // shl
                            31'b0,              // shr
                            dr[30:0],           // rol
                            d[30:0] };          // ror
    
    I suppose that is because that line is no longer after changing the definition from:
    wire [7:0][30:0] ri = { 31'b0,              // rev
                            {31{d[31]}},        // sar
                            {31{ci}},           // rcl
                            {31{ci}},           // rcr
                            31'b0,              // shl
                            31'b0,              // shr
                            dr[30:0],           // rol
                            d[30:0] };          // ror
    
    How to fix this?
  • Did I get it backwards? Should I change this:
    wire [7:0][30:0] ri
    
    to this:
    wire [30:0] ri[7:0]
    
  • Heater.Heater. Posts: 21,230
    edited 2018-01-15 03:04
    As far as I can tell your original offending line should be:
    reg [31:0] r  [0:511] // 512 times 32-bit registers.
    
    Or perhaps:
    reg [31:0] r  [511:0] // 512 times 32-bit registers.
    
    Not sure why Chip has everything reversed. Perhaps it does not matter provided everything is consistent.
  • Heater. wrote: »
    As far as I can tell your original offending line should be:
    reg [31:0] r  [0:511] // 512 times 32-bit registers.
    
    Or perhaps:
    reg [31:0] r  [511:0] // 512 times 32-bit registers.
    
    Not sure why Chip has everything reversed. Perhaps it does not matter provided everything is consistent.
    Well, it seems that Yosys is not as tolerant as the commercial FPGA tools. It doesn't like Chip's syntax.

  • IceStorm doesn't do SystemVerilog. If you look for a Xilinx port of P1v the translation has already been done. I use that version in my github fork for greater compatibility.

    I've built the P1v with IceStorm. The synthesis was successful, but when programmed it didn't work. Don't let that discourage you, it could be fixed now or maybe the 5k chip is different. I want to try it with iCEcube, but have been working on other projects.
  • Heater.Heater. Posts: 21,230
    From what I see in the standards document: IEEE Standard Verilog® Hardware Description Language - IEEE Std 1364-2001
    (Revision of 1995) the original syntax is wrong.

    See section "3.10.3.1.1 Array declarations" here:
    http://www-inst.eecs.berkeley.edu/~cs150/fa06/Labs/verilog-ieee.pdf

    Unless there has been a new standard since then.

    I would think that

    reg [511:0] [31:0] r;

    Is a two dimensional array of 1 bit registers. Where as

    reg [31:0] r [0:511]

    Is a one dimensional array of 512, 32 bit registers.

    Subtly different.


  • Any idea where I can find a Xilinx port of P1v?
  • Heater.Heater. Posts: 21,230
    edited 2018-01-15 03:38
    This needs fixing.

    The Icarus Verilog simulator does not like it either:
    $ cat hello.v
    module main;
    
      reg [31:0] r1  [0:511];
    
      reg [511:0] [31:0]  r2;
    
      initial
        begin
          $display("Hello, World");
          $finish ;
        end
    endmodule
    
    heater@surface:~$ iverilog -o hello hello.v
    hello.v:5: syntax error
    hello.v:5: error: syntax error in reg variable list.
    
  • jmgjmg Posts: 15,144
    edited 2018-01-15 03:44
    David Betz wrote: »
    Any idea where I can find a Xilinx port of P1v?

    perhaps links in here ?
    http://forums.parallax.com/discussion/165514/p1v-for-digilent-arty-fpga-board-xilinx-artix-7

    which I think leads to here
    https://github.com/jacgoudsmit/P1V/tree/rel/HDL
  • YanomaniYanomani Posts: 1,524
    edited 2018-01-15 04:47
    @Ariba

    I'm a little confused because your original post I want to comment does actually resides in the P2 thread from where the current one spined off.

    For the sake of clarity, I'll partly reproduce it here, between quotes...

    "You anyway need to solder a few things to make the UPDuino usable. I always add a few more bypass caps. If you want to use the PLL you need to add a bypass cap at the Vpll."

    In order to use the PLL, did you ever soldered the recommended 10uF(CLF) and 100nF(CHF) filter caps between VCCPLL and board's GND?

    I'm asking this because the SG48 package does not have a dedicated GNDPLL pin; its solely GND connection is thru the package paddle, as in the P2 package, and all the literature I could grab from Lattice, including the "iCE40 sysCLOCK PLL Design and Usage Guide" and the "Hardware Check List", does clearly states that GNDPLL has an internal-only connection that MUST NOT (capitals due to Lattice's texts) be externally connected to the board's ground.

    My own conclusion (that, sure, must be subjected for referal, to people with better knowledge about that device, since I have almost none) is the following: between dismissing a recommended filter at the PLL power source, and risking a noisy ground loop into a very sensitive circuit, caused by the lack of an available pin at the frame, they choose the first option, yet undocummented.

    I'll proudly accept your referal, for sure! :lol:

    Henrique
  • jmg wrote: »
    I don't see the needed changes in any branches there. Perhaps they aren't needed?

    Here is a list of all the changes needed: https://github.com/SaucySoliton/P1V/commit/89c5ba8a584dcee94d695de77c3df631bc423467 It looks like I did not yet upload my IceStorm build files.

    I got the code from here: forums.parallax.com/discussion/157004/propeller-1-running-on-pipistrello-xilinx-spartan6-lx45
  • I just uploaded my IceStorm P1V work to https://github.com/SaucySoliton/P1V
    Don't be surprised if the final binary doesn't work.

    After packing:
    IOs 30 / 206
    GBs 0 / 8
    GB_IOs 0 / 8
    LCs 4730 / 7680
    DFF 1211
    CARRY 282
    CARRY, DFF 200
    DFF PASS 739
    CARRY PASS 14
    BRAMs 32 / 32
    WARMBOOTs 0 / 1
    PLLs 0 / 2

    After placement:
    PIOs 30 / 206
    PLBs 769 / 960
    BRAMs 32 / 32

    After routing:
    span_4 11188 / 29696
    span_12 1983 / 5632

  • AribaAriba Posts: 2,682
    edited 2018-01-15 05:34
    Yanomani wrote: »
    @Ariba

    I'm a little confused because your original post I want to comment does actually resides in the P2 thread from where the current one spined off.

    For the sake of clarity, I'll partly reproduce it here, between quotes...

    "You anyway need to solder a few things to make the UPDuino usable. I always add a few more bypass caps. If you want to use the PLL you need to add a bypass cap at the Vpll."

    In order to use the PLL, did you ever soldered the recommended 10uF(CLF) and 100nF(CHF) filter caps between VCCPLL and board's GND?
    ...
    Henrique

    When I tried the PLL I just noticed that it does not work because it lacks a filter capacitor, so I soldered a 1 uF 0603 Cap at the position shown in the attached picture (the right one). If you look at the schematic of the UPDuino, there are only 3 100nF bypass Cs, so I also added such an 1uF at the voltage regulators (the left one in the picture, and the same on the backside for the 1.2V regulator).

    I have not studied the Lattice papers about it, sometimes it's better to just rely on common sense :smile: The PLL works fine with that capacitor soldered to nearest available Ground.


    P1V:
    I also used the Pipistrello source for P1V on Lattice parts, it's standard Verilog and the ROM is already minimized.

    Andy

    341 x 155 - 33K
  • jmgjmg Posts: 15,144
    Ariba wrote: »
    ...
    When I tried the PLL I just noticed that it does not work because it lacks a filter capacitor, so I soldered a 1 uF 0603 Cap at the position shown in the attached picture (the right one). If you look at the schematic of the UPDuino, there are only 3 100nF bypass Cs, so I also added such an 1uF at the voltage regulators (the left one in the picture, and the same on the backside for the 1.2V regulator).

    Wow, just 3 100nF is nowhere enough, looking at the AMS1117 data, they are quite vague and only say this
    " The circuit design used in the AMS1117 series requires the use of an output capacitor as part of the device frequency compensation.
    The addition of 22µF solid tantalum on the output will ensure stability for all operating conditions. When the adjustment terminal is bypassed with a capacitor to
    improve the ripple rejection, the requirement for an output capacitor increases. The value of 22µF tantalum covers all cases of bypassing the adjustment terminal. Without bypassing the
    adjustment terminal smaller capacitors can be used with equally good results. To further improve stability and transient response of these devices larger values of output capacitor can be used. "

    - no values defined for Cin ?

    The older 1117 series have rather high IQ of 5mA, it may be smarter to tell the UPDuino designer to revise the PCB to

    a) include PLL decoupling
    b) read the datasheets - most LDOs need input and output caps, of significant value (not 100nF)
    c) look at the more modern parts like ST's LDL1117 - this has 350mV dropout, 250uA (typ) Iq, higher PSRR and lower noise.

    ST say this about CAPS for LDL1117
    "Input and output capacitor selection
    The LDL1117 requires external capacitors to assure the regulator control loop stability.
    Any good quality ceramic capacitor can be used but, the X5R and the X7R are suggested
    since they guarantee a very stable combination of capacitance and ESR over the
    temperature range. The input/output capacitors should be placed as close as possible to
    the relative pins. The LDL1117 requires an input capacitor with a minimum value of 1 μF.
    This capacitor must be placed as close as possible to the input pin of the device and
    returned to a clean analog ground. The control loop of the LDL1117 is designed to work
    with an output ceramic capacitor. Other type of capacitors may be used, as long as they
    meet the requirements of minimum capacitance and equivalent series resistance (ESR), as
    shown in Figure 20: "Stability plan (VOUT = 5 V)" and Figure 21: "Stability plan (VOUT =1.2 V)".
    To assure stability, the output capacitor must maintain its ESR and capacitance in the
    stable region, over the full operating temperature range.
    The suggested combination of 1 μF input and 4.7 μF output capacitors offers a good
    compromise among the stability of the regulator, optimum transient response and total PCB
    area occupation."


  • AribaAriba Posts: 2,682
    edited 2018-01-15 07:07
    jmg

    Yes, it's a miracle that the UPDuino even works. Beside the Caps, the layout is horrible (GND routed with smallest wires all over the board).
    But it works! As mostly: the practice does not fit the theory. For me it shows that the UltraPlus device is not as demanding as other FPGAs, thanks to the lower power and lower frequencies.

    The owner of GnarlyGrey is a former Lattice employee, but not a hardware guy. The layout was done by a student in Sri Lanka. Maybe the job got advertised on an internet platform, and the cheapest was chosen - who knows, just my guess.

    Now that the UltraPlus parts are available as chips, it may be better to design my own board.
    There is a board in the works by the icestorm guys: https://pbs.twimg.com/media/DTWqZ_EWsAIdT7w.jpg

    Andy


  • jmgjmg Posts: 15,144
    Ariba wrote: »
    ...
    Now that the UltraPlus parts are available as chips, it may be better to design my own board.
    There is a board in the works by the icestorm guys: https://pbs.twimg.com/media/DTWqZ_EWsAIdT7w.jpg

    More caps on that one :)
    Looks to include a FT2232H too, which is common and allows a user UART and SPI Pgm links
    Not easily seen is a crystal, but maybe they use a 12MHz oscillator module, to give another FPGA clock source option ?

    Are there any SCH links ?

  • AribaAriba Posts: 2,682
    edited 2018-01-15 09:19
    There is a KiCAD schematic here: https://github.com/esden/icebreaker
    and some jpegs on the Twitter account.

    It's a community design, you can chat with the developer on Gitter (Link on the Github site).

    They use the 12MHz from the FT2232H also as FPGA clock.
  • David BetzDavid Betz Posts: 14,511
    edited 2018-01-15 17:27
    This is probably a dumb question but why won't this compile?
    wire [30:0] ri[7:0] = { 31'b0,
                            31'b0,
                            31'b0,
                            31'b0,
                            31'b0,
                            31'b0,
                            31'b0,
                            31'b0 };
    
    Isn't this declaring an 8 element array of 31 bit entries? So why can't I initialize it with 8 31 bit values?
  • Heater.Heater. Posts: 21,230
    I'm no verilog guru but:

    What you have there is a bunch of wires. What does it mean to initialize a bunch or wires? They have no memory.

    What you can do is connect wires to other things. Registers or perhaps other wires or perhaps fixed values. Such connections can be made with the "assign" statement.

    So this does compile:
    `
    $ cat hello.v
    module hello;
    
       reg [31:0] r1[7:0];
       assign ri = { 31'b0,
                     31'b0,
                     31'b0,
                     31'b0,
                     31'b0,
                     31'b0,
                     31'b0,
                     31'b0 };
      initial
        begin
    
          $display("Hello, World");
          $finish ;
        end
    endmodule
    
    heater@surface:~$ iverilog -o hello hello.v
    heater@surface:~$ vvp hello
    Hello, World
    
    See also:
    https://inst.eecs.berkeley.edu/~cs150/Documents/Nets.pdf











  • My impression was that initializing a wire simply means connecting it to something else. In my case, I was connecting some wires to a constant zero. In any case, this is just a simplified version of something that is in the p1v source code in the file cog_alu.v.
  • Heater.Heater. Posts: 21,230
    I see what you mean. I don't know. Rules is rules :)


  • David BetzDavid Betz Posts: 14,511
    edited 2018-01-15 19:42
    I now see that the code that SaucySoliton posted has it this way:
    wire [255:0] ri     = { 32'b0,              // rev
                            {32{d[31]}},        // sar
                            {32{ci}},           // rcl
                            {32{ci}},           // rcr
                            32'b0,              // shl
                            32'b0,              // shr
                            dr[31:0],           // rol
                            d[31:0] };          // ror
    
    wire [63:0] rot     = {ri[i[2:0]*32 +: 32], i[0] ? dr : d} >> s[4:0];
    
    It looks like he widened each entry to 32 bits so he could use the "*32" syntax to simulate indexing into a double dimension array with a single dimension array. Does the "*32" term instantiate a multiplier or just a shift which I guess can be implemented simply by connecting the wires at an offset? If so, why couldn't he have continued to use 31 bit entries?
Sign In or Register to comment.