Shop OBEX P1 Docs P2 Docs Learn Events
WooHoo!!!! - PortB - Clean Room Attempt — Parallax Forums

WooHoo!!!! - PortB - Clean Room Attempt

mindrobotsmindrobots Posts: 6,506
edited 2014-08-16 20:30 in Propeller 1
EDIT: Thanks to a pointer from PIK33, IT LIVES!!!!!

On Monday I started looking at adding PortB on paper and Tuesday morning, I saw that PIK33 had already posted his PortB code. Yay for the community, boo for me!

So, I'm been pressing along with my intended changes and trying to get it to work without looking at his thread or his implementation - mostly for a learning exercise for me now than anything else. I'm sure his implementation is better than mine.

I've had all the code in and have been struggling with pin assignments and getting the portb pins to even show up as assignable. My latest problem is that I get this message when trying to compile.
Error (287084): Symbolic name "pinB_in" is used but not defined as a group

In top.tdf I have this code:
pin        [31..0]    : tri;
pinB        [31..0]    : tri;
.
.
.
.
-- pins

    core.pin_in[]    = io[];

    pin[].in        = core.pin_out[];
    pin[].oe        = core.pin_dir[];
    
    io[]            = pin[].out;
    
    -- PORTB pins
    
    core.pinB_in[]    = iob[];

    pinB[].in        = core.pinB_out[];
    pinB[].oe        = core.pinB_dir[];
    
    iob[]            = pinB[].out;

In dig.v, I have this:
input        [31:0]    pin_in,            // pin state inputs
input        [31:0]     pinB_in,         // pin state inputs - PORTB
.
.
.
// pins

assign pin_out        = outx[7] | outx[6] | outx[5] | outx[4] | outx[3] | outx[2] | outx[1] | outx[0];
assign pin_dir        = dirx[7] | dirx[6] | dirx[5] | dirx[4] | dirx[3] | dirx[2] | dirx[1] | dirx[0];
assign pinB_out       = outx[7] | outx[6] | outx[5] | outx[4] | outx[3] | outx[2] | outx[1] | outx[0];
assign pinB_dir       = dirx[7] | dirx[6] | dirx[5] | dirx[4] | dirx[3] | dirx[2] | dirx[1] | dirx[0];
In cog.v, I have this:
input        [31:0]    pin_in,            // pins
output        [31:0]    pin_out,
output        [31:0]    pin_dir,
input        [31:0]    pinB_in,            // pins for PORTB
output        [31:0]    pinB_out,
output        [31:0]    pinB_dir
.
.
.
// pins

assign pin_out        = (outa | ctra_pin_out | ctrb_pin_out | vid_pin_out) & dira;
assign pinB_out        = (outb | ctra_pin_out | ctrb_pin_out | vid_pin_out) & dirb;

assign pin_dir        = dira;
assign pinB_dir        = dirb;

There may be a few otehr places I've added code. Basically, everyplace there was an io, I created an iob and where there was a pin_something, I created a pinB_something (I know rather a brute force approach).

No, I can't figure out why Quartus is picking on my pinB_in and not the original pin_in. Any ideas before I give up and go look at PIK33's code?

Thanks!

Comments

  • pik33pik33 Posts: 2,366
    edited 2014-08-14 12:55
    Look at .inc files, they have to be changed too.
    Now I have somethig better than only port B. A 32bit system bus for the Propeller. Tomorrow will try to connect and test all of this
  • mindrobotsmindrobots Posts: 6,506
    edited 2014-08-14 13:58
    pik33 wrote: »
    Look at .inc files, they have to be changed too.
    Now I have somethig better than only port B. A 32bit system bus for the Propeller. Tomorrow will try to connect and test all of this

    Thanks! That was so (NOT) obvious!

    No I am past that hurdle, so I need to do some pin decoding nadn assigning and then see if it works......I'm thinking it won't. :frown:

    A system bus sounds like fun!
  • mindrobotsmindrobots Posts: 6,506
    edited 2014-08-14 19:26
    How long have you wished for a P1 that cold run this code???
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
    PUB Main
      dira[0] := 1
      outa[0] := 1
      dirb[0] := 1
      outb[0] := 1
      repeat
        outa[0] := !outa[0]
        outb[0] := !outb[0]
        waitcnt(clkfreq / 10 + cnt)
    

    I just made a couple changes (forgot one spot in addition to the hint PIK33 provided) and now I have a 64 PIN (as soon as I map the last 7 someplace) Propeller!!! I'd have video but my iPhone battery is dead.

    I still have to test and figure out the counter and video but it looks like basic I/O (or at least basic /O) is working.

    Chip is right, this is addictively fun and at this point, I'm just hacking and still don't know what all it can do!

    As a side note, the person that came up with Figure 3-8 and Figure 3-9 in the DE0-Nano User Manual should really be taken out into the wilderness and left with nothing but a map of the same quality as their figures. One by product of this should be better pin mapping to connector cheat sheet for us Nano owners.

    I still haven't looked at PIK33's implementation yet. I'm going to stay in "clean room" mode until I try the counters and video.

    Time to just sit back in the warm glow of my blinking PortA and Port B LEDs for a while!!
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-08-14 20:12
    Congrats! It sure is addictive.
  • jazzedjazzed Posts: 11,803
    edited 2014-08-14 20:16
    Congrats Rick.
    mindrobots wrote: »
    Time to just sit back in the warm glow of my blinking PortA and Port B LEDs for a while!!
  • pik33pik33 Posts: 2,366
    edited 2014-08-14 22:15
    mindrobots wrote: »
    I still haven't looked at PIK33's implementation yet. I'm going to stay in "clean room" mode until I try the counters and video.

    Nothing is very different or better in my implementation, I only didn't this
    assign pinB_out        = (outb | ctra_pin_out | ctrb_pin_out | vid_pin_out) & dirb;
    
    
    I think (test this!) this duplicates counters and video pins on portb. Maybe having portb with ctr and vid enabled is good but it need some additional work to configure these circuits
    I used only assign pinb_out=outb&dirb which gave me "pure" port.

    And then I even removed this "&dirb", so I have independen dirb and outb ports=64 bits of output, then 32 bits of inb input. You have only to connect dirb in the top file and remove this tristate buffer,
    Then you have 96 bits of system bus. 32 bit data in/data out. Some higher dirb pins for R/~W and strobe, and then 28..30 bit of dirb as an address bus
  • ksltdksltd Posts: 163
    edited 2014-08-16 13:40
    I don't believe adding B registers (in, out, dir) is the right approach for getting more IO.

    The vast majority of code references a single pin at a time. Having all 32 in a single register has perilously little upside.

    Instead, I'd suggest extending the architecture by adding 9 new instructions and defining the architecture to have 512 IO pins. The instructions are: IOSET, IOClr, IORead, IOWrite, IODirIN, IODirOut, IODir, IOWait0, IOWait1

    These instructions each designate an IO pin through use of the existing source operand mechanisms. When the address form is used, only the nine LSBs of the addressed value are used, the others are ignored.

    Some of the instructions have an implied operand that is either zero or one. Others use the contents of the Carry Flag.

    IOSet - Pin := 1
    IOClr - Pin := 0
    IORead - Carry := Pin
    IOWrite - Pin := Carry
    IODirIn - Pindirection := In
    IODirOut - Pindirection := Out
    IODir - Pindirection := Carry

    IOWait0 and IOWait1 stop subsequent execution until the pin designated by the source operand has the value indicated

    Backwards compatibility with the use of INA, OUTA and DIRA is straightforward as are WaitPEQ and WaitPNE. GPIOs 0..31 have slightly richer capabilities because those operations allow simultaneous access to those 32 pins - but since there's no way to extend that in a general fashion, I don't see the benefit given that those 32 can be accessed simultaneously and that ought to be sufficient for applications that benefit from that capability.

    The actual number of GPIOs becomes an implementation decision.
  • mindrobotsmindrobots Posts: 6,506
    edited 2014-08-16 17:22
    ksltd wrote: »
    I don't believe adding B registers (in, out, dir) is the right approach for getting more IO.
    The beauty of having the Verilog source is that you are free to pursue any updates that you feel are the "right" approach and others can pursue what they believe is the "right" approach. Just grab the code, grab a copy of Quartus and an FPGA and have at it. In your examples, you'll also need the sources for one of the compiler tools so you can implement your new instructions. I (and certainly others on the forum) are wishing you the best success!

    I'm looking forward to trying out your 9 new instructions and 512 I/O pins and see how they compare to the "perilous" 32 bit ports we've been using all these years.

    Considering I have no verilog experience and really wasn't ready or able to modify any of the development tools to add instructions, I'm rather proud of my ability to pull off this now insignificant and pointless exercise. The majority of the PortB support is already built into the existing Propeller architecture which makes it a very economical way to add I/O pins regardless of how perilous their use may actually be. Thank you for bringing me back to reality and pointing out the "right' approach for increasing the number or I/O pins available to me for free with minimal implementation effort.

    Also, feel free to open your open thread with your design ideas, contributions and accomplishments. I'm sure no one will mind testing you theories, suggesting the right way for you to implement your code an ultimately test your running verilog on an FPGA.

    Thank you for your comments!
  • TubularTubular Posts: 4,702
    edited 2014-08-16 19:44
    Yes the P2 is a bit like what ksltd suggests, with SetP etc.

    On the larger FPGAs (eg DE2-115 / -150) there's plenty of i/o, and each cog's Port B could actually be individual to each cog, for applications where that made sense. PortA could remain common. Just one way to achieve > 256 GPIO.
  • User NameUser Name Posts: 1,451
    edited 2014-08-16 20:30
    ksltd wrote: »
    The vast majority of code references a single pin at a time. Having all 32 in a single register has perilously little upside.

    What code? ARM code, probably. That's because "one pin at a time" is about the only way to use the jumbled-up I/O on an ARM. The less the Propeller's I/O looks like the average ARM Cortex chip, the better. :)
Sign In or Register to comment.