Shop OBEX P1 Docs P2 Docs Learn Events
Added COGS define. — Parallax Forums

Added COGS define.

thoththoth Posts: 75
edited 2014-09-15 13:28 in Propeller 1
I added a COGS define that can be set from 4 to 8. When set to 4 the hub ram cog select shift register defined in dig.v runs twice as fast and compiles happen twice as fast too. I used top.v instead of top.tdf but couldn't use tim.v. I tried using tim.v in the original distro and it fails there too. My simple "Hello" spin program doesn't work. The board is recognized and the code loads but nothing prints on the terminal screen.

If anyone is interested in testing the code on a DE0 the project files in the archive are complete. I'll be testing it for the next few days but I figure the more the merrier. Just don't think of it as beta yet. Maybe not even alpha.

Look in top.v, dig.v and hub.v for the changes.

Comments

  • roglohrogloh Posts: 5,791
    edited 2014-09-12 00:02
    @thoth,
    is you archive complete? I can't find the file that has COGS defined, only files that use it.
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-09-12 01:25
    Dam Windows 8.1
    IE11 doesn't save the file as rar. Firefox saves as rar but Windows cannot extract.
    These days I expect it to be supported as standard - now to find a W8 rar extract program :(
  • thoththoth Posts: 75
    edited 2014-09-12 06:10
    rogloh wrote: »
    @thoth,
    is you archive complete? I can't find the file that has COGS defined, only files that use it.

    No, I accidentally deleted top.v when cleaning it for zipping. The new archive has top.v. That's alpha for ya.
  • thoththoth Posts: 75
    edited 2014-09-12 06:11
    Cluso99 wrote: »
    Dam Windows 8.1
    IE11 doesn't save the file as rar. Firefox saves as rar but Windows cannot extract.
    These days I expect it to be supported as standard - now to find a W8 rar extract program :(

    The archive is now in zip format.
  • ElectrodudeElectrodude Posts: 1,658
    edited 2014-09-12 07:36
    Cluso99 wrote: »
    Dam Windows 8.1
    IE11 doesn't save the file as rar. Firefox saves as rar but Windows cannot extract.
    These days I expect it to be supported as standard - now to find a W8 rar extract program :(

    Did you try 7-zip?
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-09-12 17:50
    Thanks thoth.

    Electrodude,
    I downloaded win-rar.
    I am finding all sorts of issues with W8 but I need to make it work. Hopefully W9 will be better.
  • thoththoth Posts: 75
    edited 2014-09-14 17:00
    The COGS addition is broken so don't waste any time trying it out. I will remove the archive from the first post and restore it when I have working code.
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-09-14 17:59
    thoth,
    What would be nice once you get the hub working for 4 cogs or less, is a table where the VGA etc can be defined per cog. Currently I just compile with VGA on cog 0 only (hardcoded for cog 0). I would like a define table like..
    define VGA (1,0,0,0,1,0,0,0)
    which would compile VGA for cogs 0 & 4.
    Extending this,
    define COGRAM (8,2,2,2,8,2,2,2)
    would compile 8KB for cogs 0 & 4 with the others being 2KB.
    I have these parts working for hardcoded values but I don't know how to setup a table and how to use it.
    Tks.
  • Willy EkerslykeWilly Ekerslyke Posts: 29
    edited 2014-09-14 23:28
    Cluso99 wrote: »
    What would be nice once you get the hub working for 4 cogs or less, is a table where the VGA etc can be defined per cog. Currently I just compile with VGA on cog 0 only (hardcoded for cog 0). I would like a define table like..
    define VGA (1,0,0,0,1,0,0,0)
    which would compile VGA for cogs 0 & 4.

    As-is the minimum number of Cogs is 3 because the code in hub.v references "current cog - 2". I've no idea whether this can be circumvented..

    You can have flexible VGA assignment. This is how I do it:

    In my top module:
    localparam  VIDCOGS     = 32'h00000000;                     // bit N set if cog N has video circuit (so -1 = all)
    

    In dig.v:
    module  dig
        #(
            parameter           VIDCOGS     = -1,               // default all Cogs have video
            ...
        )
    ...
    ...
    generate
        for (i=0; i<NUMCOGS; i++)
        begin : coggen
            cog    
                #(
                    .COGID      (i),
                    .HASVID     (VIDCOGS & (1 << i))
                )
    ...
    
    (Obviously, the VIDCOGS param is passed to the instantiation of dig.)

    And finally in Cog.v:
    module  cog
        #(
            parameter           COGID   = 0,                    // id of instantiated Cog (must be overidden!)
            parameter           HASVID  = 1                     // by default has video circuit
        )
    ...
    ...
    generate 
        if (HASVID)
            cog_vid cog_vid_  ( .clk_cog    (clk_cog),
                                .clk_vid    (plla),
    ...
    

    For the record I've got my P1V fully parameterized for 3 to 32 cogs and 8 to 32 locks (independent of #cogs). Having > 8 cogs requires augmenting the COGINIT instruction so to that end I'm currently extending OpenSpin to handle that plus your AUGD/DS, rogloh's PUSH/POPHUB and my MUL/S instructions.

    When I'm happy with the code I'll post the Verilog and OpenSpin.
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-09-15 00:21
    Willy,
    Thanks for that. Quite simple once you know how.

    I like the >8 cogs and the MUL/S instruction.

    Looking forward to your code and OpenSin mods.
  • thoththoth Posts: 75
    edited 2014-09-15 08:33
    Would you try the spin code snippet at the bottom of this comment and see if it works for you when COGS is set to less than 8? It doesn't for me. CogNew comes back with expected numbers but I only get a couple of cogs actually firing up and returning the greetings message. I think it has to do with the way the hub code works. It wouldn't surprise me to find that there are dependencies in Chip's code that will make mods more difficult than just adding a few defines and params. He obviously wrote this with the idea of 8 cogs firmly in mind. Assumptions, no doubt, ensued. I find digging through the hub code very frustrating.

    This is my intro to FPGA and Verilog and it's a grunt. I'm not at all sure I've got the persistence to pursue the project. So far it's been pretty frustrating. I just don't grok the way he names stuff. I find the two and three letter abbreviations that change meanings for the same letters one module to another very confusing. I'm all for short names but I make a point to provide a dictionary to give a little help to people coming after. Maybe I'm just thick as a brick but what does this mean?
    always @(posedge clk_cog or negedge nres)
    if (!nres)
        cog_e <= 8'b00000001;
    else if (ena_bus && sys && ac[2:1] == 2'b01)
        cog_e <= cog_e & ~num_dcd | {8{!ac[0]}} & num_dcd;
    

    I realize that it's a shift register but figuring that out took a lot of work since I have no idea what ac or num_dcd stand for so I end up spending a lot of time in the RTL viewer.

    And for what good purpose? Is this really the way maintainable Verilog code should be written? I'm not denying for a minute that Chip's very talented and good and all that. But, like everything he does, this code is stamped with his highly idiosyncratic, terse style.

    I have a feeling that Chip could have given everyone a run for the money in those Iverson one line APL contests. Fun to write but not so fun to decipher. For instance, he doesn't give an inch when it comes to putting in a few parentheses to make precedence clear.
    always @(posedge clk_cog)
        match <= m[4] && (i[ol+1:ol] == 2'b01 ^ (i[ol+1] ? cnt : pin_in & s) == d);
    

    would be a lot clearer as:
    always @(posedge clk_cog)
        match <= m[4] && ( (i[ol+1:ol] == 2'b01 ^ (i[ol+1] ) ? cnt : pin_in & s) == d);
    

    at least it is to me. I'm sure reading becomes second nature after working with it for a decade - along with knowing in advance what you're doing. But it makes a beginner like me start thinking that these Lisp guys are onto something. Anything but infix!!!

    Parallax is famous for it's clear introductory treatment of computers and that's why it has been accepted as a teaching aid. This code fails that test I think. Of course, again, I just may not have what it takes. I'm well aware of my many deficiencies. And it's obvious that Chip didn't write it for anyone else to read.

    Anyway - off my soapbox and back to the issue at hand.

    The code below works as expected on the stock distro. If I adjust the "i" index in the cog generator to a value between 8 and 4 I get the correct number of cogs responding but I also get, as expected, false indications from the cog leds and the return value from CogNew.

    The takeaway here is that I can't count on CogNew and the enable leds as an indication that the cog has really fired up and is running correctly.
    {{ COGTest.spin }}
    
    CON
      _clkmode        = xtal1 + pll16x           ' Feedback and PLL multiplier
      _xinfreq        = 5_000_000                ' External oscillator = 5 MHz
    
    VAR
      byte Cog
      long stack[60]
      
    OBJ
      Term : "Parallax Serial Terminal"
    
    
    PUB Main
      Term.Start(9600)
      Term.CharIn
      Term.Str(string("Starting Cogs ",13,13))
      repeat 6
        Cog := CogNew( Howdy, @stack )
        WaitCnt( clkfreq/2 + cnt )
        Term.Str( string("CogNew returns ") )
        Term.Dec(Cog)
      repeat
      
    PUB Howdy
      Term.Str(string("Greetings from "))
      Term.Dec( CogId )
      Term.NewLine
      repeat
    
  • jac_goudsmitjac_goudsmit Posts: 418
    edited 2014-09-15 09:12
    thoth wrote: »
    Would you try this code and see if it's working for COGS less than 8?

    You should set up separate stacks for each cog, instead of one stack for all cogs.

    Also, I seem to remember that there's a problem with just putting "repeat" in the code without a body (I think the execution just skips the loop), but I may be wrong.

    ===Jac
  • thoththoth Posts: 75
    edited 2014-09-15 09:26
    You should set up separate stacks for each cog, instead of one stack for all cogs.

    Also, I seem to remember that there's a problem with just putting "repeat" in the code without a body (I think the execution just skips the loop), but I may be wrong.

    ===Jac

    That's true enough. But the fact is that this code works as expected on a Quickstart board and on the stock distro of P1v. The stack is only used by one cog one time and then the next cog reuses it. I think that's safe enough in this case. My rather fixed idea is that if it works on a QuickStart and on the Distro then it should work everywhere.
  • thoththoth Posts: 75
    edited 2014-09-15 09:43
    You should set up separate stacks for each cog, instead of one stack for all cogs.

    Also, I seem to remember that there's a problem with just putting "repeat" in the code without a body (I think the execution just skips the loop), but I may be wrong.

    ===Jac

    From the manual:

    Since Statement(s) is really an optional part of REPEAT, the REPEAT command by itself can be
    used as an endless loop that does nothing but keep the cog active.
  • Willy EkerslykeWilly Ekerslyke Posts: 29
    edited 2014-09-15 12:54
    thoth,

    Be careful when changing the number of Cogs. It's not just a matter of, say, reducing the generate loop iterations to 4. Consider this code in hub.v that generates the id for COGID
    always @(posedge clk_cog)
    if (ena_bus && sys)
        sys_q <= ac[2:0] == 3'b001  ? { bus_sel[7] || bus_sel[6] || bus_sel[5] || bus_sel[0],       // cogid
                                        bus_sel[7] || bus_sel[4] || bus_sel[3] || bus_sel[0],
                                        bus_sel[6] || bus_sel[4] || bus_sel[2] || bus_sel[0] }
                                    : num;                                                          // others
    

    Only one bit of the bus_sel vector will be 1'b1 and if it's bus_sel[3] for example then the result of all the ||'s will be 3'b010, or cogId = 2. The result is one less than the active bus_sel because of the hub timing. The critical thing is that if bus_sel[0] is 1'b1 then the above results in cogId = 7 which for a 4-Cog P1V is not right!

    Similarly the code that selects the next free cog for COGNEW will happily pick number 4 even though you've only got 0 through 3!
  • thoththoth Posts: 75
    edited 2014-09-15 13:28
    thoth,

    Be careful when changing the number of Cogs. It's not just a matter of, say, reducing the generate loop iterations to 4. Consider this code in hub.v that generates the id for COGID
    always @(posedge clk_cog)
    if (ena_bus && sys)
        sys_q <= ac[2:0] == 3'b001  ? { bus_sel[7] || bus_sel[6] || bus_sel[5] || bus_sel[0],       // cogid
                                        bus_sel[7] || bus_sel[4] || bus_sel[3] || bus_sel[0],
                                        bus_sel[6] || bus_sel[4] || bus_sel[2] || bus_sel[0] }
                                    : num;                                                          // others
    

    Only one bit of the bus_sel vector will be 1'b1 and if it's bus_sel[3] for example then the result of all the ||'s will be 3'b010, or cogId = 2. The result is one less than the active bus_sel because of the hub timing. The critical thing is that if bus_sel[0] is 1'b1 then the above results in cogId = 7 which for a 4-Cog P1V is not right!

    Similarly the code that selects the next free cog for COGNEW will happily pick number 4 even though you've only got 0 through 3!

    I think that totally confirms what I said above -
    I think it has to do with the way the hub code works. It wouldn't surprise me to find that there are dependencies in Chip's code that will make mods more difficult than just adding a few defines and params. He obviously wrote this with the idea of 8 cogs firmly in mind. Assumptions, no doubt, ensued. I find digging through the hub code very frustrating.

    I can do another case statement with proper decode for the various numbers of cogs. That's what I did for ORing together the cogs to the i/o bus - and it's not pretty. It would work I think.

    This is a clear case where an assumption of 8 cogs is built implicitly into the code. This is why I'm inclined to back away from the idea of having a COGS parameter at all. Nice in theory but in practice it means dealing with the hub logic at a level deeper than my understanding goes. If I had a few years of Verilog experience it might be different. But maybe not!

    Thing is, what else lurks in the hub darkness ready to pounce? And for what reward?
Sign In or Register to comment.