Bug 490 - Complete peripheral set including litex for first functional OpenPOWER Core (ls180)
Summary: Complete peripheral set including litex for first functional OpenPOWER Core (...
Status: RESOLVED FIXED
Alias: None
Product: Libre-SOC's first SoC
Classification: Unclassified
Component: Source Code (show other bugs)
Version: unspecified
Hardware: PC Linux
: High normal
Deadline: 2020-10-30
Assignee: Luke Kenneth Casson Leighton
URL:
Depends on: 493 508
Blocks: 383
  Show dependency treegraph
 
Reported: 2020-09-11 00:52 BST by Cole Poirier
Modified: 2022-06-28 13:27 BST (History)
2 users (show)

See Also:
NLnet milestone: NLNet.2019.02.029.Coriolis2
total budget (EUR) for completion of task and all subtasks: 2000
budget (EUR) for this task, excluding subtasks' budget: 2000
parent task for budget allocation: 199
child tasks for budget allocation:
The table of payments (in EUR) for this task; TOML format:
lkcl = { amount = 1750, submitted = 2021-04-24, paid = 2021-05-01 } staf = { amount = 250, submitted = 2021-04-24, paid = 2021-04-24 }


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Cole Poirier 2020-09-11 00:52:37 BST
Litex:

 * SPI master
 * SPI sdcard
 * UART (tx/rx)
 * SDRAM (SDR)
 * GPIO (16)
 * EINT (2)
 * PWM (3)
 * I2C master
 * SDMMC
 * JTAG
Comment 1 Luke Kenneth Casson Leighton 2020-09-16 23:14:54 BST
ok i cranked the priority down just a leeetle bit :)

i also just committed some preliminary changes, cut out the pins not needed,
put in that verilog stuff we talked about 

commit 093ddebb6ba44f3edd291d699d775c6821b8d620 (HEAD -> master, origin/master)
Author: Luke Kenneth Casson Leighton <lkcl@lkcl.net>
Date:   Wed Sep 16 22:54:15 2020 +0100

    make a start on LS180 platform
Comment 2 Luke Kenneth Casson Leighton 2020-09-17 02:06:13 BST
next bit is to hook up chips4makers jtag which has a wishbone bus master on it, and investigate ways to test it.
Comment 3 Staf Verhaegen 2020-09-17 11:55:47 BST
Current way of testing for JTAG implemented in Chips4Makers JTAG is use of
cocotb and .svf files.
.svf files are standardized text format for running tests through JTAG. In the Chips4Makers repo is a cocotb infrastructure for playing back these .svf files
in a RTL simulation. I used cocotb as in the Retro-uC some nmigen modules are used which are wrapper around VHDL and Verilog code and pysim can't handle those.
In theory now cxxsim should be able to handle anything yosys can synthesize.

For pure nmigen code maybe the JTAG simulation infrastructure could be ported
from cocotb to pysim/cxxsim. But I guess due to the use of litex the libre-SOC
won't be a pure nmigen design either.

Nice thing is that the tested .svf files in simulation could also be used later to test the chips. For Retro-uC I actually did both test .svf file in cocotb and later on FPGA using openOCD to play the .svf file.
Comment 4 Luke Kenneth Casson Leighton 2020-09-17 16:57:20 BST
(In reply to Staf Verhaegen from comment #3)

> For pure nmigen code maybe the JTAG simulation infrastructure could be ported
> from cocotb to pysim/cxxsim. But I guess due to the use of litex the
> libre-SOC
> won't be a pure nmigen design either.

no, however i can at least do a basic unit test in nmigen, checking that
JTAG creates WB requests correctly.

> 
> Nice thing is that the tested .svf files in simulation could also be used
> later to test the chips. For Retro-uC I actually did both test .svf file in
> cocotb and later on FPGA using openOCD to play the .svf file.

i like it!  i would really like to work out how to use coriolis2 simulation
of the netlist / transistors, at some point.
Comment 5 Luke Kenneth Casson Leighton 2020-09-17 17:03:25 BST
ok so you scan/parse the svf file and then can
send jtag commands through cocotb to the hardware?

https://gitlab.com/Chips4Makers/c4m-jtag/-/blob/master/c4m/cocotb/jtag/c4m_jtag_svfcocotb.py

that should be pretty easy to adapt to nmigen.
Comment 6 Luke Kenneth Casson Leighton 2020-09-19 11:51:23 BST
//--------------------------------------------------------------------------------
// Auto-generated by Migen (731c192) & LiteX (35929c0f) on 2020-09-18 23:11:06
//--------------------------------------------------------------------------------
module sim(
    output reg serial_tx,
    input wire serial_rx,
    input wire sys_clk,
    output reg [12:0] sdram_a,
    inout wire [15:0] sdram_dq,
    output reg sdram_we_n,
    output reg sdram_ras_n,
    output reg sdram_cas_n,
    output reg sdram_cs_n,
    output reg sdram_cke,
    output reg [1:0] sdram_ba,
    output reg [1:0] sdram_dm,
    input wire [7:0] gpio_in,
    input wire [7:0] gpio_out,
    output reg spi_master_clk,
    output reg spi_master_mosi,
    output reg spi_master_cs_n,
    input wire spi_master_miso,
    output reg sdcard_clk,
    inout wire sdcard_cmd,
    inout wire [3:0] sdcard_data,
    output reg spisdcard_clk,
    output reg spisdcard_mosi,
    output reg spisdcard_cs_n,
    input wire spisdcard_miso
);

ha!  this is progressing much faster than i expected.

Staf: for GPIO what is the definition of the IO pads?  should we do
very simple 8x GPIO-in and 8x GPIO-out, and not try to mix the two?
i am tempted to go this route because i means not having to write
any Litex code.

if we try a GPIO bi-directional IOpad it would mean having to write
some Litex code to add the CSRs for switching the direction, and
to output verilog code-fragments maybe actually adding that to
migen (!)

i really do not want to do that.
Comment 7 Staf Verhaegen 2020-09-19 14:20:06 BST
It's up to you to decide, I do have preference to have the bidirectional possibility for GPIO.
For bidirectional IO you should get have three signal ending op _i, _o and _oe. If I remember correctly I think TriState from migen should give these signals. How the value of the oe signal is best handled in Litex I leave that up to you.
Comment 8 Luke Kenneth Casson Leighton 2020-09-19 14:25:13 BST
(In reply to Staf Verhaegen from comment #7)
> It's up to you to decide, I do have preference to have the bidirectional
> possibility for GPIO.
> For bidirectional IO you should get have three signal ending op _i, _o and
> _oe. If I remember correctly I think TriState from migen should give these
> signals. How the value of the oe signal is best handled in Litex I leave
> that up to you.

ah excellent, so as long as migen supports that and you're happy with it
then i am too.  the last thing i wanted was to be writing migen code.
Comment 9 Luke Kenneth Casson Leighton 2020-09-19 15:01:07 BST
hm.  litex is generating the following verilog:

module ls180(
    input wire [15:0] gpio,
);

wire [15:0] main_pads;
wire main_tstriple0_o;
wire main_tstriple0_oe;

assign main_pads[0] = main_tstriple0_oe ? main_tstriple0_o : 1'bz;
assign main_tstriple0_i = main_pads[0];


all of which looks dodgy to me.  gpio is an input only, for a start.
plus, i would kinda expect that those 3 _o, _oe and _i would be
"externally exposed" so you could connect them up manually.

don't know.  am putting it back to 8-in 8-out for now.
Comment 10 Luke Kenneth Casson Leighton 2020-09-19 15:22:23 BST
running into yosys massive amounts of memory issues (12GB)

<daveshah> The solution will either to have LiteX use memory compiler primitives instead; or remove all calls to memory_map in your Yosys script so you are left with $mem cells (less ideal but maybe you can use memory_bram to map them to your ASIC primitives)
Comment 11 Luke Kenneth Casson Leighton 2020-09-19 15:55:17 BST
Removing $memory\mem[6227]$68502 ($dff) from module ls180.
Removing $memory\mem[6226]$68500 ($dff) from module ls180.
Removing $memory\mem[6225]$68498 ($dff) from module ls180.
Removing $memory\mem[6224]$68496 ($dff) from module ls180.
Removing $memory\mem[6223]$68494 ($dff) from module ls180.
Removing $memory\mem[6222]$68492 ($dff) from module ls180.
Removing $memory\mem[6221]$68490 ($dff) from module ls180.
Removing $memory\mem[6220]$68488 ($dff) from module ls180.
Removing $memory\mem[6219]$68486 ($dff) from module ls180.
Removing $memory\mem[6218]$68484 ($dff) from module ls180.
Comment 12 Luke Kenneth Casson Leighton 2020-09-19 15:55:43 BST
      New connections: $memory\mem$rdmux[0][7][48]$b$89345 [13] = $memory\mem$rdmux[0][7][48]$b$89345 [11]
    Consolidated identical input bits for $mux cell $memory\mem$rdmux[0][8][98]$89877:
      Old ports: A=$memory\mem$rdmux[0][8][98]$a$89878, B=$memory\mem$rdmux[0][8][98]$b$89879, Y=$memory\mem$rdmux[0][7][49]$a$89347
      New ports: A={ $memory\mem$rdmux[0][8][98]$a$89878 [31:26] $memory\mem$rdmux[0][8][98]$a$89878 [24:21] $memory\mem$rdmux[0][8][98]$a$89878
Comment 13 Luke Kenneth Casson Leighton 2020-09-21 17:35:58 BST
(In reply to Staf Verhaegen from comment #3)

> For pure nmigen code maybe the JTAG simulation infrastructure could be ported
> from cocotb to pysim/cxxsim. But I guess due to the use of litex the

i have a *very* basic unit test now with DMI2JTAG operational and reading
IDCODE

https://git.libre-soc.org/?p=soc.git;a=blob;f=src/soc/debug/dmi2jtag.py;h=119aaf9860ff0f52e93f8fd2945cd7333c1a9962;hb=fd902da6f694e68a4c664786fd02857866d90d3e#l239

staf looking at the VCD files it seems that the addresses are stored in
reverse-bit-order which is quite interesting but has no impact on functionality

i may add one more unit test (JTAG wishbone read/write) and then i am going
to add this to ls180.

staf it would be nice to have DMI2TAG added to c4m jtag tap.py
Comment 15 Luke Kenneth Casson Leighton 2020-09-22 15:09:43 BST
currently investigating JTAGREMOTE module in litex

https://github.com/enjoy-digital/litex/blob/master/litex/build/sim/core/modules/jtagremote/jtagremote.c

this *should* make it possible to speak "openocd bitbang" remotely,
by linking jtag simulated pins to a TCP port.


also to investigate:

https://github.com/lowRISC/opentitan/tree/master/hw/dv/dpi/jtagdpi
https://github.com/lowRISC/opentitan/blob/master/util/openocd/target/lowrisc-earlgrey.cfg
https://github.com/lowRISC/opentitan/blob/master/util/openocd/interface/sim-jtagdpi.cfg
Comment 16 Luke Kenneth Casson Leighton 2020-09-22 16:06:25 BST
Staf: i just managed to (successfully) get openocd connected to
litex "jtagremote" module under simulation.

Info : JTAG tap: libresoc.tap tap/device found: 0x000018ff (mfg: 0x47f (<invalid>), part: 0x0001, ver: 0x0)

however i had to add this to the openocd.cfg file:

jtag newtap libresoc tap -irlen 1 -expected-id 0x000018ff

that should be "irlen 4" because i set ir_width=4.

the only reason i can think of why that would happen is if the bit-order
for IR is inverted in c4m JTAG.
Comment 17 Staf Verhaegen 2020-09-22 20:22:17 BST
Would be strange if such a bug would be there as I successfully tested JTAG interface with openocd on FPGA.
See for example this video: https://chips4makers.io/blog/blink-demo.html#blink-demo
I don't know though if this was still using the VHDL version of the JTAG interface or the nmigen one.

Anyway won't have time in near future to look deeper into this.
Comment 18 Luke Kenneth Casson Leighton 2020-09-22 20:46:07 BST
(In reply to Staf Verhaegen from comment #17)
> Would be strange if such a bug would be there as I successfully tested JTAG
> interface with openocd on FPGA.
> See for example this video:
> https://chips4makers.io/blog/blink-demo.html#blink-demo
> I don't know though if this was still using the VHDL version of the JTAG
> interface or the nmigen one.

this is pure nmigen (c4m).

i got it to "work" with this in openocd:

jtag newtap libresoc tap -irlen 4 -irmask 0xf -ircapture 0xf -expected-id 0x000018ff

> Anyway won't have time in near future to look deeper into this.

ok.  i will investigate more in-depth tomorrow after sorting out some
alternative to openocd.
Comment 19 Jacob Lifshay 2020-09-22 20:52:16 BST
idk if we will have time, but it might be useful to implement gdb's remote protocol over a serial port.
Comment 20 Luke Kenneth Casson Leighton 2020-09-22 21:00:28 BST
(In reply to Jacob Lifshay from comment #19)
> idk if we will have time, but it might be useful to implement gdb's remote
> protocol over a serial port.

in RTL?  very unlikely.  turns out that openocd (which is "working" for
a given definition of "work") can talk gdb on one side and remote-network
protocol on the other.
Comment 21 Luke Kenneth Casson Leighton 2020-09-23 17:57:57 BST
i've redesigned litex GPIO and SD/MMC Card to have signals that
comprise "gpio_i", "gpio_o", "gpio_oe" and the same for sdcard
cmd and data.

this involves literally cut/pasting verbatim the entire litex GPIO
and SDCard classes, duplicating the code, and replacing the pinout
class with a suitable replacement.

it's a mess, and the same mess will extend to SDRAM.

FORTNUATELY, for SDRAM, the concept of alternative PHYs is an
established practice, so i "only" have to create a replacement
that munges the names of dq into triple-functions dq_i, dq_o, dq_en
Comment 22 Luke Kenneth Casson Leighton 2020-09-23 22:49:48 BST
(In reply to Luke Kenneth Casson Leighton from comment #21)

> FORTNUATELY, for SDRAM, the concept of alternative PHYs is an
> established practice, so i "only" have to create a replacement
> that munges the names of dq into triple-functions dq_i, dq_o, dq_en

done.

commit 28638852cc74861c4fb5095aa1e712f26b3f364a (HEAD -> master, origin/master)
Author: Luke Kenneth Casson Leighton <lkcl@lkcl.net>
Date:   Wed Sep 23 22:44:56 2020 +0100

    change litex sdram pinouts to ASIC type
Comment 23 Luke Kenneth Casson Leighton 2020-09-24 12:50:28 BST
sfaf should i be calling c4m_jtag TAP.add_io for *all* pins?  that
seems somewhat excessive, and now that i think about it it's a *lot* of
work:

* call add_ios in nmigen
* expose both the pad wires *and* the the jtag-io wires (IOConn Record)
* add all IOConn records to the litex libresoc core.py code
* get litex to generate the ls180.v
* join up the libresoc core (in verilog) to ls180.v
* re-import ls180.v into nmigen
* *finally* wire up the connections between jtag-io and pads

i might actually do that last step in litex (ls180soc.py) to save some
messing about, and reduce the number of wires routed between different
compilers.

so if it's ok with you i'm going to do the 16 GPIO, and the 2nd UART.
this will cover:

* IOType.In (uart1 rx)
* IOType.Out (uart1 rx)
* IOType.InTriOut (gpios 0-15 yes i worked out how to do o/i/oe)

also: do you have a template for re-building the actual SoC with the
c4m IO cells?  i can throw something together if not but i will need
some guidance / pointer-to-some-code.
Comment 24 Staf Verhaegen 2020-09-24 19:28:05 BST
(In reply to Luke Kenneth Casson Leighton from comment #23)
> sfaf should i be calling c4m_jtag TAP.add_io for *all* pins?  that
> seems somewhat excessive,

Currently only the low-level implementation of the JTAG interface is finished where you create for each IO cell a corresponding IOConn. For higher level implementation is to integrate JTAG interface inside the nmigen platform. Just like you now have XilinxPlatform you would also have ASICPlatform or C4MPlatform. If possible I would like it to implement so that using .add_resources() you could define the type of the cells (e.g. pin 2,3 are UART). The platform would then automatically instantiate the right IO cell and add it to the JTAG boundary scan.
Unfortunately this is still TODO.

> and now that i think about it it's a *lot* of work:
> 
> * call add_ios in nmigen
> * expose both the pad wires *and* the the jtag-io wires (IOConn Record)
> * add all IOConn records to the litex libresoc core.py code
> * get litex to generate the ls180.v
> * join up the libresoc core (in verilog) to ls180.v
> * re-import ls180.v into nmigen
> * *finally* wire up the connections between jtag-io and pads

Why do you need to bring IOConn into litex ?
* You define peripherals in litex
* You get a verilog file out of litex with the IO signals as inputs and outputs of the top verilog module.
* You bring this top verilog cell in nmigen using Instance()
* For each IO you do an add_io() on the TAP and connect the corresponding signals from the litex top in nmigen to the core part of the IOConn. The pad part of the IOConn you bring out as the new top signal in a generated verilog file.
* This new top goes then to synthesis and P&R

> 
> i might actually do that last step in litex (ls180soc.py) to save some
> messing about, and reduce the number of wires routed between different
> compilers.
> 
> so if it's ok with you i'm going to do the 16 GPIO, and the 2nd UART.
> this will cover:
> 
> * IOType.In (uart1 rx)
> * IOType.Out (uart1 rx)
> * IOType.InTriOut (gpios 0-15 yes i worked out how to do o/i/oe)
> 
> also: do you have a template for re-building the actual SoC with the
> c4m IO cells?  i can throw something together if not but i will need
> some guidance / pointer-to-some-code.

As said above, for the moment bring out the pad part of the IOConns as input/outputs of the top verilog file together with clk and rst. I will see with Jean-Paul how we add the IO cells to it.
Later on also the nmigen platform should take care of this and instantiate the right IO cells but as said this is currently not implemented.
Comment 25 Luke Kenneth Casson Leighton 2020-09-24 21:43:04 BST
ok i have just finished (not tested yet), it will need review and testing.


(In reply to Staf Verhaegen from comment #24)
> (In reply to Luke Kenneth Casson Leighton from comment #23)
> > sfaf should i be calling c4m_jtag TAP.add_io for *all* pins?  that
> > seems somewhat excessive,
> 
> Currently only the low-level implementation of the JTAG interface is
> finished where you create for each IO cell a corresponding IOConn.

yes.  i do that here at line 47:
https://git.libre-soc.org/?p=soc.git;a=blob;f=src/soc/debug/jtag.py;hb=HEAD#l47


> For
> higher level implementation is to integrate JTAG interface inside the nmigen
> platform.

yes, that's 

> Just like you now have XilinxPlatform you would also have
> ASICPlatform or C4MPlatform.

yes, this is here (ls180.py) which derives from GenericPlatform, it would
form the basis of an ASICPlatform

https://git.libre-soc.org/?p=soc.git;a=blob;f=src/soc/litex/florent/libresoc/ls180.py;hb=HEAD


> If possible I would like it to implement so
> that using .add_resources() you could define the type of the cells (e.g. pin
> 2,3 are UART).

at some point i want to completely replace litex with something similar to
OpenTITAN except written in nmigen.


> The platform would then automatically instantiate the right
> IO cell and add it to the JTAG boundary scan.
> Unfortunately this is still TODO.

i have some partial infrastructure done, today, it is not fully automatic
because that would need a lot more work in litex and i am not prepared
to commit huge resources to something that's based on an unstable base
(migen).

however.... i import the same "Pins" structure from soc.debug.jtag and
use exactly that in the litex core.py to create the "map" from the
(now verilog) core to litex:

https://git.libre-soc.org/?p=soc.git;a=blob;f=src/soc/litex/florent/libresoc/core.py;hb=HEAD

that is done at line 220 (declare another instance of Pins, similar to
back in soc/debug/jtag.py line 47, and enumerate them)


> Why do you need to bring IOConn into litex ?

because something has to connect up the IOConn to the actual litex peripheral
pads.  there are two ways to do it:

1) get litex to do it
2) get nmigen to do it.

this 2nd way requires passing the peripheral signals *in* to the verilog
instantiation of the core (test_issuer.v): litex still therefore needs
to know what they are, in some fashion.

i decided to go (2) because it greatly simplifies the "third stage" - the
nmigen "instantiation" of the combined litex-core verilog file.

all that the final phase needs to do now is: connect to the IO pads.
and i *think*... that actually might be a "null operation".

less work for you!

> * You define peripherals in litex
> * You get a verilog file out of litex with the IO signals as inputs and
> outputs of the top verilog module.
> * You bring this top verilog cell in nmigen using Instance()

ah, unfortunately, the litex sim code assumes that the nmigen test_issuer
is a verilog instance.

> * For each IO you do an add_io() on the TAP and connect the corresponding
> signals from the litex top in nmigen to the core part of the IOConn.

this is the bit that i have already done *before* it goes into litex.

why?

well... how can you call add_io on the tap *after* the TAP was created
in the *first* one?

and: how can we run a nmigen simulation of the TAP.add_io() calls if it
is brought in as a verilog instance?

we can't.  it would have to be done through verilator (which has to
be written) or cocotb (which has to be written) both of which are time-consuming


> The pad
> part of the IOConn you bring out as the new top signal in a generated
> verilog file.

i have implemented it slightly differently, but making exactly the same
connections.

instead of nmigen (3rd phase) instantiating the TAP and calling TAP.add_io
it is done in the FIRST phase (because it is one JTAG class instance,
the same one used for Wishbone and DMI)


> As said above, for the moment bring out the pad part of the IOConns as
> input/outputs of the top verilog file together with clk and rst. 

already done, connected up, the pad parts of the IOConns are connected
in litex [1] for GPIO, [2] for UART

so the phase (3) $Instance is, i have a feeling, basically not needed.


> I will see
> with Jean-Paul how we add the IO cells to it.
> Later on also the nmigen platform should take care of this and instantiate
> the right IO cells but as said this is currently not implemented.

ok.  well, aside from unit tests which i will look at tomorrow, that is
currently the blocker for this because it's done.


[1] GPIO ls180soc IOconn pad connections

https://git.libre-soc.org/?p=soc.git;a=blob;f=src/soc/litex/florent/ls180soc.py;h=9c7547f7078522cedccb5cc38f2beed6e58b7f6b;hb=HEAD#l389

[2] UART ls180soc IOconn pad connections

https://git.libre-soc.org/?p=soc.git;a=blob;f=src/soc/litex/florent/ls180soc.py;h=9c7547f7078522cedccb5cc38f2beed6e58b7f6b;hb=HEAD#l374
Comment 26 Luke Kenneth Casson Leighton 2020-09-24 21:49:41 BST
(In reply to Luke Kenneth Casson Leighton from comment #25)

> > For
> > higher level implementation is to integrate JTAG interface inside the nmigen
> > platform.
> 
> yes, that's 

an unfinished sentence :)

that's what i've done.  everything is declared back in nmigen:

* TAP.add_ios
* TAP.add_wishbone
* TAP.add_dmi

otherwise we cannot run nmigen simulation unit tests of the IOConns.
Comment 27 Luke Kenneth Casson Leighton 2020-10-03 21:31:35 BST
these are now defined by pinmux ls180 spec

https://git.libre-soc.org/?p=pinmux.git;a=blob;f=src/spec/ls180.py;hb=HEAD

the nmigen JTAG module sets up IOconn instances and also takes a pinset.

https://git.libre-soc.org/?p=soc.git;a=blob;f=src/soc/debug/jtag.py;hb=HEAD

the pinset dictionary currently hardcoded as dummy_pinset() is now autogenerated by the pinmux

Issuer creates one of these JTAG modules and through the pinset creates a suite of ports (JTAG core and io pads) which end up in the public interface in the verilog module.

https://git.libre-soc.org/?p=soc.git;a=blob;f=src/soc/simple/issuer.py;hb=HEAD#l83


using the EXACT same pinmux Pin definitions, Litex LS180Platform creates two sets of IO resources, one for JTAG pads one for JTAG core and connects up the core ones to the test_issuer verilog with make_jtag_conn

https://git.libre-soc.org/?p=soc.git;a=blob;f=src/soc/litex/florent/libresoc/core.py;hb=HEAD#l236

where a "normal" litex core would connect direct to the *platform* IO resource, because JTAG has been connected to that litex instead connects to the *CPU* IO resource(s) which were routed via the JTAG IOconn MUXes and back out again through test_issuer

https://git.libre-soc.org/?p=soc.git;a=blob;f=src/soc/litex/florent/ls180soc.py;hb=HEAD#l431

in the coriolis2 layout the ioring is created by using once again the EXACT same pinmux spec to create a JSON file with the mappings between LITEX peripheral names and coriolis2 IO pin names

https://git.libre-soc.org/?p=soclayout.git;a=blob;f=experiments9/coriolis2/ioring.py;hb=HEAD

in this way we get automated centrally specified IO without getting into a manual duplication mess.
Comment 28 Luke Kenneth Casson Leighton 2021-04-20 15:53:43 BST
declaring this one done, moving to coriolis2 project as it was needed for
the layout to complete.  staf EUR 250 for the help with JTAG TAP