machinekit / mksocfpga

Hostmot2 FPGA code for SoC/FPGA platforms from Altera and Xilinx
30 stars 40 forks source link

Is it viable to add (Hostmot2) pinmuxing to the mksocfpga ? #18

Closed the-snowwhite closed 11 months ago

the-snowwhite commented 8 years ago

Update: 4-june-2016 Finaly made it to the short answer: ... YES:

https://github.com/the-snowwhite/mksocfpga_hm3/tree/hostmot3

The pinmux functionality adds about 2-3% gates to the "standard" 1 GPIO port project that uses around 36%.

At startup all the pins (0-34) are configured as Straight pins, pins 35 and 36 are currendly hardwired to leds 1 and 2.

The routing of each pin is controlled by newly added registers: 0x1120, and upwards(to max below: 0x1200 ): Each 32 bit register controls 4 pins via an 8-bit byte. (default max number of pins are 144).

THe changes can be ported back into the hostmot2 version (I have put all the hm2 core generation into wrappers in the Hostmot3 project, work that is unfinished ATM.)

The ability to "live" pin mux, makes it unnecessary to run separate builds for changing pin assignments, however does break comparability with the original hostmot2.vhd, as minor changes are necessary to add this functionality, back into the mksocfpga2 project.


TODO:

Changes need to be made to be able to select 1- 4 (34 -36 pin) gpio ports.

As it is now the LEDs are "sticking out" as they are routed through an separate output port, and so not included in the "normal" hm2 IO regs.

Right now all 36 GPIO port pins are muxed, making it very clumsy to have to "hardwire in the 2 led's pr gpio port".

@dkhughes + @cdsteinkuehler Just a heads up on some plans for being able to do more flexible routing, + (Being able to register the I/O end of the hostmot2 core, So that design partitioning gets possible). Here are my findings so far:

The problem with being able to route the inputs / outputs to/from the hm2 cores is that the bi-dir tristable I/O's are routed from the hostmot2 top file upwards through the top file, and then to the actual physical pins.

The problem with that is that: "Modern fpga's do not support internal tristate routing".

So whats happening is that the the wires are routed as either inputs or outputs from the hostmot2 core + the tristate and input / output logic is the applied at the pin / pads (GPIO).

The hdl compiler software will not tolerate any thing else that a direct connection from source to destination, making the only way to do something like the DB-25 adaptor board rewireing in an ugly mess directly in the top file as static single wire reassignments, hardwired into each compilation.

It may be possible to do it more clean looking as a systemverilog function, however that does not change the fact that the "mux" is hardwired into each config --> compiled bitfile.


The other challange is that the pin pads I/O functions are controlled by setting values in the hostmot2 rom, (DDR section around addresses 0x1000 - 0x1414 )from where there is no easy way to route the I/O (gpio core functional) control lines like output enable, opendrain, Invert , etc.


I am currently bisecting the hdl sources in the Hostmot3 project, and the best solution I can see to this problem would be to move this section of memory out of the hm2 idrom "blob", and implement this section of memory directly attached to a gpio controller interfacing to the pads, and separate the hm2 core wires into dedicated input and output busses(per hm2 core collection).

The new gpio + memory block controller could then have a pinmux attatched that then routes the in / outs from the hm2 cores to the desired pin pads (GPIO_x), via adding a new register for this between addresses 0x1414 and 0x1500. (to route 32 wires to unique positions it takes 32+31+30+29+...+2 bits, for routing control, I think I ended up with something like 36 bits trying to calculate in my head, however I really bad at doing numbers .. :-) )

the-snowwhite commented 8 years ago

Quick search Link collection of what seems to be out there and available.


PINCTRL (PIN CONTROL) subsystem
This document outlines the pin control subsystem in Linux

This subsystem deals with:

- Enumerating and naming controllable pins

- Multiplexing of pins, pads, fingers (etc) see below for details

- Configuration of pins, pads, fingers (etc), such as software-controlled
  biasing and driving mode specific pins, such as pull-up/down, open drain,
  load capacitance etc.

https://www.kernel.org/doc/Documentation/pinctrl.txt

Pin Control Sybsystem – Building Pins and
GPIO from the ground up

http://dflund.se/~triad/papers/pincontrol.pdf

Software Reconfigurable Pin Multiplexing

http://www.flex-logix.com/pin-muxing/

High-level block diagram of Snickerdoodle

Differentiating the board even more than the number of GPIO is the design choice that allows users to pair Snickerdoodle’s Wi-Fi chip with a cellphone app called Connect. Once paired, Connect facilitates uploading custom field-programmable gate array (FPGA) configuration files to the board, controlling such  operations as GPIO assignments, pin multiplexing, and overall system performance.

Use a cell phone app to load custom configurations to the snickerdoodle's FPGA

http://usadye.ru/full-desc/aHR0cDovL21ha2V6aW5lLmNvbS8yMDE1LzEwLzEyL3NuaWNrZXJkb29kbGUtZGV2LWJvYXJkLWZwZ2EtYXJtLXByb2Nlc3Nvci98fEdQSU8gQ2FyZHx8MHx8TmV3c3x8MA

http://vytm.in/Lg6JRw#http://makezine.com/2015/10/12/snickerdoodle-dev-board-fpga-arm-processor/

the-snowwhite commented 7 years ago

GPIO mux functionality added in this merge: https://github.com/machinekit/mksocfpga/pull/87 https://github.com/machinekit/mksocfpga/commit/dcacaab2ec7f7c16b874d2acdb40c56e39a29605

dkhughes commented 7 years ago

Just in case you haven't seen it, but this is working on the Zynq side already. Input/output bus is split at the top level, and I exposed the DDR register. I did it to allow implementation of gated logic on the I/O without using a software component in the HAL since as you mentioned, internal connections must be resolved. See:

https://github.com/machinekit/mksocfpga/blob/master/HW/zynq-ip/hm2_ip_wrap/src/hostmot2_ip_wrap.vhd.in#L110

As a side note, why the push to verilog? The rest of the project is already in VHDL.

the-snowwhite commented 7 years ago

I have implemented the GPIO mux so that each GPIO destination is controlled via hm2 registers: https://github.com/machinekit/mksocfpga/blob/master/HW/QuartusProjects/Common/gpio_adr_decoder_reg.sv#L26

This way it is possible to control the routing directly from the hal.

How do you control the routing ?

About language preferences: I understand how to create functional code in Verilog / Systemverilog. (C-like in my eyes) VHDL Is only readable for me as the philosophy behind how it is supposed to work is incomprehensive for a self learner like me. :-)

dkhughes commented 7 years ago

How do you control the routing ?

I used the DDR registers that are already built in here:

https://github.com/machinekit/mksocfpga/commit/cd601ac6625114ae2c5d8b6e9e91a7ba3e44e0fc

Then, in a hal file you use the standard gpio.NNN.is_ouput syntax and the hostmot2 driver handled the rest automatically. It was the path of least resistance at the time to splitting the buses and still having HAL control.

the-snowwhite commented 7 years ago

But … this is confusing:

I am talking about routing to from any physical GPIO pin on the HW board.

Are you able to route the fixed outputs of the hm2 cores like PWM og Stepper pins with this scheme ?

On 8 Sep 2017, at 14.18, dkhughes notifications@github.com wrote:

How do you control the routing ?

I used the DDR registers that are already built in here:

cd601ac https://github.com/machinekit/mksocfpga/commit/cd601ac6625114ae2c5d8b6e9e91a7ba3e44e0fc Then, in a hal file you use the standard gpio.NNN.is_ouput syntax and the hostmot2 driver handled the rest automatically. It was the path of least resistance at the time to splitting the buses and still having HAL control.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/machinekit/mksocfpga/issues/18#issuecomment-328088103, or mute the thread https://github.com/notifications/unsubscribe-auth/AKifnD1xtsYbk5kIX45Hz5irDaXVlwQpks5sgTCsgaJpZM4IaT8d.

dkhughes commented 7 years ago

Oh, I see what you are saying. To route the pin functions around you would have to add a big mux to all of output pins, then have the selectors based on every available output pin. The DDR could still be used the way I showed for input/output determination and allow connecting the pins to this mux. Man, that would be a big mux though - and one that needs to be optional. Designs like mine are already up against the placement limit and while that functionality would be nice I wouldn't want to buy a larger FPGA for it.

dkhughes commented 7 years ago

I guess for small designs it would work well - 32IO would be like 32 32->1 muxes connected to the GPIO ddr selection component...I'm running 72IO though currently.

cdsteinkuehler commented 7 years ago

On 9/8/2017 11:15 AM, dkhughes wrote:

I guess for small designs it would work well - 32IO would be like 32 32->1 muxes connected to the GPIO ddr selection component...I'm running 72IO though currently.

Yeah, I can see where it might be useful, but it's a lot of logic and almost anything that doesn't need to be changed live at run-time can be done with ZERO extra logic by just playing with the FPGA project and PIN_* files.

It would, however, be nice to have the I/O signals at the top-level of the project NOT be tri-state. I've run into issues with the passing of tri-state signals from the top level to the hostmot2 instance, which some of the FPGA tool chains don't really like.

So I like pushing the I/O buffers and DDR signal to the top level, just make the "any-to-any" mux part optional.

-- Charles Steinkuehler charles@steinkuehler.net