FPGARelated.com
Forums

High-level synthesis

Started by Benjamin Couillard March 21, 2019
On 25/03/2019 10:58, Svenn Are Bjerkem wrote:
> On Sunday, March 24, 2019 at 11:01:05 PM UTC+1, Jan Coombs wrote: >> On Sun, 24 Mar 2019 08:46:20 -0700 (PDT) >> Svenn Are Bjerkem wrote: >> >>> On Sunday, March 24, 2019 at 8:31:34 AM UTC+1, Jan Coombs wrote: >>>> On Sat, 23 Mar 2019 19:45:06 -0700 (PDT) >>>> Kevin Neilson wrote: >>>> >>>>> "Hardware Construction Language": that's a good phrase. I write a lot of Matlab that generates Verilog. I wish I didn't have to, but that's the way it is. >>>> >>>> Could you construct and simulate with MyHDL? The verilog >>>> would then be just a simple export. [1] >>>> >>>> Jan Coombs >>> >>> I read on the myhdl discourse that there seems to be a problem with the myhdl owner not maintaining myhdl the way a proper project owner should. Care to comment on that? >> >> Yes, this is a problem. The BDFL found time to consolidate >> progress to a 0.10 release. The team look capable, but their >> interests will likely diverge/fork if the leadership does not >> improve. >> >> What else combines the constructional power of the Python >> ecosystem, with simulation speed equal to other free tools >> [1], and spits out Verilog or VHDL? > > The reason I don't write assembly these days is that gcc does the job for me *and* that there is a certain safety that gcc will not disappear because some leadership wanders off to more interesting projects. This has happened to "fast" tools in the past, and it will happen to "fast" tools in the future. When I decide to put a massive effort into learning something, I would like to know where I am heading. The current situation at myhdl is rocking my trust in it. > > It is not that I am not willing to look into new ways of resolving my development and verification tasks. I am looking into both myhdl and cocotb[2] and I use ghdl as my simulator. cocotb managed to get their things together regarding the massive improvement in ghdl[3] on vhdl-2008, myhdl seem to still think iverilog is the only way to cosimulate in the FOSS world. > > [2] http://potential.ventures/cocotb/ > [3] https://github.com/ghdl/ghdl >
Have you considered Spinal <https://github.com/SpinalHDL> ? It is a high level HDL based on Scala.
On Monday, March 25, 2019 at 1:17:02 PM UTC-4, Rob Gaddi wrote:
> On 3/23/19 9:21 PM, A.P.Richelieu wrote: > > Den 2019-03-23 kl. 05:43, skrev A.P.Richelieu: > >> Den 2019-03-22 kl. 17:11, skrev Rob Gaddi: > >>> On 3/21/19 9:37 PM, A.P.Richelieu wrote: > >>>> Den 2019-03-21 kl. 19:40, skrev Benjamin Couillard: > >>>>> It's been about 3 years since I've done any *serious* FPGA work. I > >>>>> used mostly VHDL or sometimes my own Matlab scripts to create > >>>>> automated VHDL files. > >>>>> > >>>>> I would like to know if anyone has used High-level synthesis > >>>>> recetnly for *real* work and if so, would they recommend that > >>>>> people learn it? > >>>>> > >>>>> > >>>>> > >>>> > >>>> We are working on a system where we connect an FPGA and a CPU. > >>>> The FPGA will implement almost 20-30 peripherals. > >>>> The CPU will run Linux, and will need a driver for each type > >>>> of peripheral. > >>>> > >>>> The Linux driver for each peripheral type will contain a main header > >>>> file, and a file describing the user interface (I.E: the peripheral > >>>> registers) > >>>> > >>>> A register could look like: > >>>> > >>>> typedef struct uart_mode_s { > >>>> &nbsp;&nbsp;&nbsp;&nbsp; uint32_t&nbsp;&nbsp;&nbsp; bits:4; > >>>> &nbsp;&nbsp;&nbsp;&nbsp; uint32_t&nbsp;&nbsp;&nbsp; parity:1; > >>>> &nbsp;&nbsp;&nbsp;&nbsp; uint32_t&nbsp;&nbsp;&nbsp; odd:1; > >>>> &nbsp;&nbsp;&nbsp;&nbsp; uint32_t&nbsp;&nbsp;&nbsp; encoding:2; > >>>> &nbsp;&nbsp;&nbsp;&nbsp; uint32_t&nbsp;&nbsp;&nbsp; baud:24; > >>>> } uart_mode_t; > >>>> > >>>> I use the register header file as input to a Python program to > >>>> generate the register in VHDL. The Python program will generate a > >>>> package > >>>> containing the register with a std_logic_vector, and functions which > >>>> will convert to and from a "record" so I can use the high level view > >>>> of the register in VHDL. > >>>> > >>>> If I change the C header file in the driver, then the VHDL code will > >>>> also change, due to dependencies in the build. > >>>> > >>>> Plan to have another Python program which will take a CSV > >>>> file and use the contents to instantiate peripherals, and > >>>> to generate the interface to the processor, including the address > >>>> decoding. (Perhaps a JSON file will be better, though) > >>>> > >>>> This allows me to adopt to changing requirements and save a lot of time > >>>> as well as keeping the driver and the peripheral in sync. > >>>> > >>>> I know others that do it the same way. > >>>> > >>>> AP > >>> > >>> If you haven't gotten too deep into writing your own code yet, you > >>> may want to check out a project I've been working on sporadically for > >>> a while now.&nbsp; https://github.com/NJDFan/register-maps > >>> > >>> There's also a more standard format for describing registers, > >>> IP-XACT, which like mine is XML-based.&nbsp; I found it impossibly obtuse > >>> to work with, but note it for the record. > >>> > >> > >> Thank You, > >> I will have a look. > >> I was discussing this with the guy that has generated the FPGA > >> code for my current project, and he suggested an XML based > >> approach instead of C. > >> If I was going that route, to start from a description and > >> generate both C and VHDL, I would probably use a JSON format, > >> since they are so much easier to read. > >> > >> In my mind the best way is to start off with the C driver. > >> If you like us are running Linux & U-Boot, then you > >> have an API for the driver, which needs to be followed. > >> > >> The H/W implementation of all the peripherals I have seen basically > >> suck, and the C driver implementer has to overcome all the deficiencies > >> forced upon him/her by the chip designers. > >> > >> The proper approach is to start with the API and then > >> figure out how to implement this in a driver in the most efficient way. > >> > >> spi_xfer(peripheral SPI, uint8_t src, size_t size, enum spi_flags flags) > >> { > >> &nbsp;&nbsp;&nbsp; SPI->START = flags;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Activate CS on request > >> &nbsp;&nbsp;&nbsp; strncpy(SPI->FIFO, src, size); > >> &nbsp;&nbsp;&nbsp; SPI->STOP&nbsp; = flags;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Deactivate CS on request > >> } > >> > >> Once I have the driver figured out, I already have the headers, > >> so I do not want to create XML to regenerate what I already have. > >> > >> AP > > > > Had a brief look at your stuff at > > > > * https://github.com/NJDFan/register-maps > > > > This is mainly to do address decoding, right? > > Do you have any support for the actual fields inside the registers? > > That is a primary function I would be looking for. > > > > I can actually see the use of such tool for me, > > if my C struct parser generates the XML (or JSON) > > for an intermediate representation. > > > > BR > > AP > > Yep. Registers can have fields of types signed, unsigned, or bits. > That generates VHDL records with named fields of types SIGNED, UNSIGNED, > and STD_LOGIC_VECTOR (or STD_LOGIC for single bit fields) and functions > to translate the records to/from a STD_LOGIC_VECTOR the size of the > read/write bus, as well as procedures to modify a structured register > from a write data bus that has byte enables. > > If you use the high-level API (suitable for "I want to implement these > registers on flops", not for "I want to implement a large BRAM for > this.") you wind up with the entire thing in a > t_<component_name>_regfile, which is a record type where each register > (or register array) is a field. So you wind up using things like > regfile.ctl.enable to interface with your logic.
When creating a data structure like this, is there any real reason to use std_logic_vector rather than unsigned? I tend to use either signed or unsigned for all multibit data types rather than std_logic_vector just because it is easier to type and I've never found an issue. -- Rick C. - Get a 1,000 miles of free Supercharging - Tesla referral code - https://ts.la/richard11209
On 3/25/19 3:12 PM, gnuarm.deletethisbit@gmail.com wrote:
> On Monday, March 25, 2019 at 1:17:02 PM UTC-4, Rob Gaddi wrote: >> On 3/23/19 9:21 PM, A.P.Richelieu wrote: >>> Den 2019-03-23 kl. 05:43, skrev A.P.Richelieu: >>>> Den 2019-03-22 kl. 17:11, skrev Rob Gaddi: >>>>> On 3/21/19 9:37 PM, A.P.Richelieu wrote: >>>>>> Den 2019-03-21 kl. 19:40, skrev Benjamin Couillard: >>>>>>> It's been about 3 years since I've done any *serious* FPGA work. I >>>>>>> used mostly VHDL or sometimes my own Matlab scripts to create >>>>>>> automated VHDL files. >>>>>>> >>>>>>> I would like to know if anyone has used High-level synthesis >>>>>>> recetnly for *real* work and if so, would they recommend that >>>>>>> people learn it? >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>>> We are working on a system where we connect an FPGA and a CPU. >>>>>> The FPGA will implement almost 20-30 peripherals. >>>>>> The CPU will run Linux, and will need a driver for each type >>>>>> of peripheral. >>>>>> >>>>>> The Linux driver for each peripheral type will contain a main header >>>>>> file, and a file describing the user interface (I.E: the peripheral >>>>>> registers) >>>>>> >>>>>> A register could look like: >>>>>> >>>>>> typedef struct uart_mode_s { >>>>>> &nbsp;&nbsp;&nbsp;&nbsp; uint32_t&nbsp;&nbsp;&nbsp; bits:4; >>>>>> &nbsp;&nbsp;&nbsp;&nbsp; uint32_t&nbsp;&nbsp;&nbsp; parity:1; >>>>>> &nbsp;&nbsp;&nbsp;&nbsp; uint32_t&nbsp;&nbsp;&nbsp; odd:1; >>>>>> &nbsp;&nbsp;&nbsp;&nbsp; uint32_t&nbsp;&nbsp;&nbsp; encoding:2; >>>>>> &nbsp;&nbsp;&nbsp;&nbsp; uint32_t&nbsp;&nbsp;&nbsp; baud:24; >>>>>> } uart_mode_t; >>>>>> >>>>>> I use the register header file as input to a Python program to >>>>>> generate the register in VHDL. The Python program will generate a >>>>>> package >>>>>> containing the register with a std_logic_vector, and functions which >>>>>> will convert to and from a "record" so I can use the high level view >>>>>> of the register in VHDL. >>>>>> >>>>>> If I change the C header file in the driver, then the VHDL code will >>>>>> also change, due to dependencies in the build. >>>>>> >>>>>> Plan to have another Python program which will take a CSV >>>>>> file and use the contents to instantiate peripherals, and >>>>>> to generate the interface to the processor, including the address >>>>>> decoding. (Perhaps a JSON file will be better, though) >>>>>> >>>>>> This allows me to adopt to changing requirements and save a lot of time >>>>>> as well as keeping the driver and the peripheral in sync. >>>>>> >>>>>> I know others that do it the same way. >>>>>> >>>>>> AP >>>>> >>>>> If you haven't gotten too deep into writing your own code yet, you >>>>> may want to check out a project I've been working on sporadically for >>>>> a while now.&nbsp; https://github.com/NJDFan/register-maps >>>>> >>>>> There's also a more standard format for describing registers, >>>>> IP-XACT, which like mine is XML-based.&nbsp; I found it impossibly obtuse >>>>> to work with, but note it for the record. >>>>> >>>> >>>> Thank You, >>>> I will have a look. >>>> I was discussing this with the guy that has generated the FPGA >>>> code for my current project, and he suggested an XML based >>>> approach instead of C. >>>> If I was going that route, to start from a description and >>>> generate both C and VHDL, I would probably use a JSON format, >>>> since they are so much easier to read. >>>> >>>> In my mind the best way is to start off with the C driver. >>>> If you like us are running Linux & U-Boot, then you >>>> have an API for the driver, which needs to be followed. >>>> >>>> The H/W implementation of all the peripherals I have seen basically >>>> suck, and the C driver implementer has to overcome all the deficiencies >>>> forced upon him/her by the chip designers. >>>> >>>> The proper approach is to start with the API and then >>>> figure out how to implement this in a driver in the most efficient way. >>>> >>>> spi_xfer(peripheral SPI, uint8_t src, size_t size, enum spi_flags flags) >>>> { >>>> &nbsp;&nbsp;&nbsp; SPI->START = flags;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Activate CS on request >>>> &nbsp;&nbsp;&nbsp; strncpy(SPI->FIFO, src, size); >>>> &nbsp;&nbsp;&nbsp; SPI->STOP&nbsp; = flags;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Deactivate CS on request >>>> } >>>> >>>> Once I have the driver figured out, I already have the headers, >>>> so I do not want to create XML to regenerate what I already have. >>>> >>>> AP >>> >>> Had a brief look at your stuff at >>> >>> * https://github.com/NJDFan/register-maps >>> >>> This is mainly to do address decoding, right? >>> Do you have any support for the actual fields inside the registers? >>> That is a primary function I would be looking for. >>> >>> I can actually see the use of such tool for me, >>> if my C struct parser generates the XML (or JSON) >>> for an intermediate representation. >>> >>> BR >>> AP >> >> Yep. Registers can have fields of types signed, unsigned, or bits. >> That generates VHDL records with named fields of types SIGNED, UNSIGNED, >> and STD_LOGIC_VECTOR (or STD_LOGIC for single bit fields) and functions >> to translate the records to/from a STD_LOGIC_VECTOR the size of the >> read/write bus, as well as procedures to modify a structured register >> from a write data bus that has byte enables. >> >> If you use the high-level API (suitable for "I want to implement these >> registers on flops", not for "I want to implement a large BRAM for >> this.") you wind up with the entire thing in a >> t_<component_name>_regfile, which is a record type where each register >> (or register array) is a field. So you wind up using things like >> regfile.ctl.enable to interface with your logic. > > When creating a data structure like this, is there any real reason to use std_logic_vector rather than unsigned? I tend to use either signed or unsigned for all multibit data types rather than std_logic_vector just because it is easier to type and I've never found an issue. >
Just the sake of strong typing. To my mind, a STD_LOGIC_VECTOR is a thing that does not have a numerical interpretation, and as such can't have arithmetic applied to it. An UNSIGNED has one and only one numerical interpretation, and as such can't consist of multiple bitfields doing different things. It's easier to verify the code if you do it that way, but nothing really essential. -- Rob Gaddi, Highland Technology -- www.highlandtechnology.com Email address domain is currently out of order. See above to fix.
On Monday, March 25, 2019 at 6:22:25 PM UTC-4, Rob Gaddi wrote:
> On 3/25/19 3:12 PM, gnuarm.deletethisbit@gmail.com wrote: > > On Monday, March 25, 2019 at 1:17:02 PM UTC-4, Rob Gaddi wrote: > >> On 3/23/19 9:21 PM, A.P.Richelieu wrote: > >>> Den 2019-03-23 kl. 05:43, skrev A.P.Richelieu: > >>>> Den 2019-03-22 kl. 17:11, skrev Rob Gaddi: > >>>>> On 3/21/19 9:37 PM, A.P.Richelieu wrote: > >>>>>> Den 2019-03-21 kl. 19:40, skrev Benjamin Couillard: > >>>>>>> It's been about 3 years since I've done any *serious* FPGA work. I > >>>>>>> used mostly VHDL or sometimes my own Matlab scripts to create > >>>>>>> automated VHDL files. > >>>>>>> > >>>>>>> I would like to know if anyone has used High-level synthesis > >>>>>>> recetnly for *real* work and if so, would they recommend that > >>>>>>> people learn it? > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>> > >>>>>> We are working on a system where we connect an FPGA and a CPU. > >>>>>> The FPGA will implement almost 20-30 peripherals. > >>>>>> The CPU will run Linux, and will need a driver for each type > >>>>>> of peripheral. > >>>>>> > >>>>>> The Linux driver for each peripheral type will contain a main header > >>>>>> file, and a file describing the user interface (I.E: the peripheral > >>>>>> registers) > >>>>>> > >>>>>> A register could look like: > >>>>>> > >>>>>> typedef struct uart_mode_s { > >>>>>> &nbsp;&nbsp;&nbsp;&nbsp; uint32_t&nbsp;&nbsp;&nbsp; bits:4; > >>>>>> &nbsp;&nbsp;&nbsp;&nbsp; uint32_t&nbsp;&nbsp;&nbsp; parity:1; > >>>>>> &nbsp;&nbsp;&nbsp;&nbsp; uint32_t&nbsp;&nbsp;&nbsp; odd:1; > >>>>>> &nbsp;&nbsp;&nbsp;&nbsp; uint32_t&nbsp;&nbsp;&nbsp; encoding:2; > >>>>>> &nbsp;&nbsp;&nbsp;&nbsp; uint32_t&nbsp;&nbsp;&nbsp; baud:24; > >>>>>> } uart_mode_t; > >>>>>> > >>>>>> I use the register header file as input to a Python program to > >>>>>> generate the register in VHDL. The Python program will generate a > >>>>>> package > >>>>>> containing the register with a std_logic_vector, and functions which > >>>>>> will convert to and from a "record" so I can use the high level view > >>>>>> of the register in VHDL. > >>>>>> > >>>>>> If I change the C header file in the driver, then the VHDL code will > >>>>>> also change, due to dependencies in the build. > >>>>>> > >>>>>> Plan to have another Python program which will take a CSV > >>>>>> file and use the contents to instantiate peripherals, and > >>>>>> to generate the interface to the processor, including the address > >>>>>> decoding. (Perhaps a JSON file will be better, though) > >>>>>> > >>>>>> This allows me to adopt to changing requirements and save a lot of time > >>>>>> as well as keeping the driver and the peripheral in sync. > >>>>>> > >>>>>> I know others that do it the same way. > >>>>>> > >>>>>> AP > >>>>> > >>>>> If you haven't gotten too deep into writing your own code yet, you > >>>>> may want to check out a project I've been working on sporadically for > >>>>> a while now.&nbsp; https://github.com/NJDFan/register-maps > >>>>> > >>>>> There's also a more standard format for describing registers, > >>>>> IP-XACT, which like mine is XML-based.&nbsp; I found it impossibly obtuse > >>>>> to work with, but note it for the record. > >>>>> > >>>> > >>>> Thank You, > >>>> I will have a look. > >>>> I was discussing this with the guy that has generated the FPGA > >>>> code for my current project, and he suggested an XML based > >>>> approach instead of C. > >>>> If I was going that route, to start from a description and > >>>> generate both C and VHDL, I would probably use a JSON format, > >>>> since they are so much easier to read. > >>>> > >>>> In my mind the best way is to start off with the C driver. > >>>> If you like us are running Linux & U-Boot, then you > >>>> have an API for the driver, which needs to be followed. > >>>> > >>>> The H/W implementation of all the peripherals I have seen basically > >>>> suck, and the C driver implementer has to overcome all the deficiencies > >>>> forced upon him/her by the chip designers. > >>>> > >>>> The proper approach is to start with the API and then > >>>> figure out how to implement this in a driver in the most efficient way. > >>>> > >>>> spi_xfer(peripheral SPI, uint8_t src, size_t size, enum spi_flags flags) > >>>> { > >>>> &nbsp;&nbsp;&nbsp; SPI->START = flags;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Activate CS on request > >>>> &nbsp;&nbsp;&nbsp; strncpy(SPI->FIFO, src, size); > >>>> &nbsp;&nbsp;&nbsp; SPI->STOP&nbsp; = flags;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Deactivate CS on request > >>>> } > >>>> > >>>> Once I have the driver figured out, I already have the headers, > >>>> so I do not want to create XML to regenerate what I already have. > >>>> > >>>> AP > >>> > >>> Had a brief look at your stuff at > >>> > >>> * https://github.com/NJDFan/register-maps > >>> > >>> This is mainly to do address decoding, right? > >>> Do you have any support for the actual fields inside the registers? > >>> That is a primary function I would be looking for. > >>> > >>> I can actually see the use of such tool for me, > >>> if my C struct parser generates the XML (or JSON) > >>> for an intermediate representation. > >>> > >>> BR > >>> AP > >> > >> Yep. Registers can have fields of types signed, unsigned, or bits. > >> That generates VHDL records with named fields of types SIGNED, UNSIGNED, > >> and STD_LOGIC_VECTOR (or STD_LOGIC for single bit fields) and functions > >> to translate the records to/from a STD_LOGIC_VECTOR the size of the > >> read/write bus, as well as procedures to modify a structured register > >> from a write data bus that has byte enables. > >> > >> If you use the high-level API (suitable for "I want to implement these > >> registers on flops", not for "I want to implement a large BRAM for > >> this.") you wind up with the entire thing in a > >> t_<component_name>_regfile, which is a record type where each register > >> (or register array) is a field. So you wind up using things like > >> regfile.ctl.enable to interface with your logic. > > > > When creating a data structure like this, is there any real reason to use std_logic_vector rather than unsigned? I tend to use either signed or unsigned for all multibit data types rather than std_logic_vector just because it is easier to type and I've never found an issue. > > > > Just the sake of strong typing. To my mind, a STD_LOGIC_VECTOR is a > thing that does not have a numerical interpretation, and as such can't > have arithmetic applied to it. An UNSIGNED has one and only one > numerical interpretation, and as such can't consist of multiple > bitfields doing different things. It's easier to verify the code if you > do it that way, but nothing really essential.
There is no such restriction on signed or unsigned. How does verifying the code change? Rick C.
Benjamin Couillard <benjamin.couillard@gmail.com> writes:

> I did the same in VHDL about 10 years ago. It worked well for a > medium-sized system. It was based on a code snippet posted by Jonathan > Bromley on comp.lang.vhdl
Interesting. Do you still happen to have that VHDL snippet? Personally, my projects have usually had so few registers I haven't bothered with any generator. At least in my opinion if you have, say, less than 20 registers, then who cares. However, now I have a project which has quite a lot of registers. I searched and found a Python script called hdlregs on Github. It's actually by the guy (Guy Eschemann) who does AirHDL now which is a payola web service to generate register files with an AXI4 slave interface. Hdlregs takes json as input and generates docs in HTML, VHDL code and C headers. Bus interface is simple address/data/control, user interface to regs is a single record in and another one out. The script seems to have some limitations so hardly perfect but good enough for my needs. Then again, it's in Python so easy to improve. Documentation is zero apart from one example.
Le mercredi 27 mars 2019 04:03:00 UTC-4, Anssi Saari a &eacute;crit&nbsp;:
> Benjamin Couillard <benjamin.couillard@gmail.com> writes: > > > I did the same in VHDL about 10 years ago. It worked well for a > > medium-sized system. It was based on a code snippet posted by Jonathan > > Bromley on comp.lang.vhdl > > Interesting. Do you still happen to have that VHDL snippet? >
https://groups.google.com/d/msg/comp.lang.vhdl/0JrSaPFUJ1k/JzDlR9MZVMUJ Make sure to read the whole thread as there is a small typo in the posted code. The typo is corrected in a later post.
Feel free to use RegisterWizard from Bitvis.  This is freeware - so no cost. https://bitvis.no/dev-tools/register-wizard/

The input is in JSON, and is easy to use by anyone.
It is well documented - including examples.
The generated bus interface is what we call Simple Bus Interface (SBI), which is what people some year ago would have called a simple SRAM interface.
If you need a more advanced interface you can just make a general wrapper.

If you download the open source UVVM (Universal VHDL Verification Methodology) from Github (https://github.com/UVVM/UVVM) you will get a BFM (Bus functional model) and VVC (verification component) with procedures to access the SBI interface (or Avalon or AXI4-lite) in a testbench.

- Espen
Benjamin Couillard <benjamin.couillard@gmail.com> writes:

> Le mercredi 27 mars 2019 04:03:00 UTC-4, Anssi Saari a &#4294967295;crit&#4294967295;: >> Benjamin Couillard <benjamin.couillard@gmail.com> writes: >> >> > I did the same in VHDL about 10 years ago. It worked well for a >> > medium-sized system. It was based on a code snippet posted by Jonathan >> > Bromley on comp.lang.vhdl >> >> Interesting. Do you still happen to have that VHDL snippet? >> > > https://groups.google.com/d/msg/comp.lang.vhdl/0JrSaPFUJ1k/JzDlR9MZVMUJ > > Make sure to read the whole thread as there is a small typo in the > posted code. The typo is corrected in a later post.
Thanks. Well, it looks like it will take some work to get from the snippets to a working implementation but I'll see what I can do with it.