FPGARelated.com
Forums

Code block in icestudio

Started by Josef Moellers February 13, 2020
Hi,

I'm trying to program a TinyFPGA BX to provide 3 registers to emulate an
FDC9266, the bulk will later be done using an ATMega ucontroller.

To sort out the A0,nCS,nRD,nWR,nDACK, I have inserted a code block which
should generate the following internal signals:

SEL: switch a "Mux 2:1" between the outputs of the STATUS and the DATA
IN registers
OE: enable a TRI-STATE output to the processor's data bus
DW: clock data into the DATA IN register


if (nCS == 0 || nDACK == 0)	// chip selected
begin
  SEL = A0;		// (1)
  OE = not nRD;		// (2)
  DW = not nWR;		// (3)
end

I keep getting errors "Invalid module instantiation" on lines (1), (2) ,
and (3) and "Syntax error" on line (1).
I cannot find a suitable syntax description, so I tried
* "<=" rather than "="
* if (A0 == 1) SEL = 1; else SEL = 0;
but the error does not go away.

Anyone know how to fix this?

Thanks,

Josef
On 13.02.20 10:43, Josef Moellers wrote:
> Hi, > > I'm trying to program a TinyFPGA BX to provide 3 registers to emulate an > FDC9266, the bulk will later be done using an ATMega ucontroller. > > To sort out the A0,nCS,nRD,nWR,nDACK, I have inserted a code block which > should generate the following internal signals: > > SEL: switch a "Mux 2:1" between the outputs of the STATUS and the DATA > IN registers > OE: enable a TRI-STATE output to the processor's data bus > DW: clock data into the DATA IN register > > &#8232;if (nCS == 0 || nDACK == 0) // chip selected > begin > SEL = A0; // (1) > OE = not nRD; // (2) > DW = not nWR; // (3) > end > > I keep getting errors "Invalid module instantiation" on lines (1), (2) , > and (3) and "Syntax error" on line (1). > I cannot find a suitable syntax description, so I tried > * "<=" rather than "=" > * if (A0 == 1) SEL = 1; else SEL = 0; > but the error does not go away.
Apparently 1) I need an "always @(1)" before any code 2) I need to declare the outputs "reg SEL, OE, DW" 3) It's not "not", it's "!" Still, this leaves questions: 1) I used "=", but I have also seen "<=" and both are accepted What's the difference between the two? 2) The "reg" suggests some kind of register/latch. Is this true? I just want the logic gates, no latches! Josef
On Thursday, February 13, 2020 at 7:06:39 AM UTC-5, Josef Moellers wrote:
> On 13.02.20 10:43, Josef Moellers wrote: > > Hi, > > > > I'm trying to program a TinyFPGA BX to provide 3 registers to emulate an > > FDC9266, the bulk will later be done using an ATMega ucontroller. > > > > To sort out the A0,nCS,nRD,nWR,nDACK, I have inserted a code block which > > should generate the following internal signals: > > > > SEL: switch a "Mux 2:1" between the outputs of the STATUS and the DATA > > IN registers > > OE: enable a TRI-STATE output to the processor's data bus > > DW: clock data into the DATA IN register > > > > &#8232;if (nCS == 0 || nDACK == 0) // chip selected > > begin > > SEL = A0; // (1) > > OE = not nRD; // (2) > > DW = not nWR; // (3) > > end > > > > I keep getting errors "Invalid module instantiation" on lines (1), (2) , > > and (3) and "Syntax error" on line (1). > > I cannot find a suitable syntax description, so I tried > > * "<=" rather than "=" > > * if (A0 == 1) SEL = 1; else SEL = 0; > > but the error does not go away. > > Apparently > 1) I need an "always @(1)" before any code > 2) I need to declare the outputs "reg SEL, OE, DW" > 3) It's not "not", it's "!" > > Still, this leaves questions: > 1) I used "=", but I have also seen "<=" and both are accepted > What's the difference between the two? > 2) The "reg" suggests some kind of register/latch. > Is this true? I just want the logic gates, no latches! > > Josef
You appear to be programming in Verilog which I don't know so well mostly having programmed in VHDL. I don't know that in Verilog assignment statements always have to be in a process (the always block thing). In VHDL the "top level" is to write independent assignment statements which all operate in parallel. Then inside a process (slightly different syntax from Verilog always blocks, it starts with process()) assignment statements are sequential code. To answer your question, there are two types of assignments, blocking and non-blocking. The nomenclature has never made sense to me so I don't remember which is which. Looking it up = is 'blocking' and <= is 'non-blocking'. In VHDL concurrent code always uses <=. The blocking vs. non-blocking only has meaning in sequential code since concurrent code is always executed in parallel. In a process <= means the assignment is done when the code pauses (usually when reaching the end of the process block). So if all assignments in a process use <= nothing is actually assigned until the end of the process and all are updated with the values on the right hand side of the assignments at the time they were encountered. The expression is evaluated and saved, but not assigned to the left hand side until the process stops. In a process an assignment using = in Verilog and := in VHDL is made immediately so that the value can be changed before reaching the end of the process. These are only used when you specifically need them for some reason. While they are more like what happens in non-hardware related code, HDLs mostly are coded with non-blocking assignments using <= which does not work like sequential code in other languages. This is one of several reasons why software coders can't just "pick up" an HDL language and run with it. They actually need to learn the language and not assume it works like non-HDLs. Once they come to grips with a few differences like this, it's not so special and anyone can code in HDLs. -- Rick C. - Get 1,000 miles of free Supercharging - Tesla referral code - https://ts.la/richard11209
On 13.02.20 15:43, Rick C wrote:
[...]
> You appear to be programming in Verilog which I don't know so well mostly having programmed in VHDL. I don't know that in Verilog assignment statements always have to be in a process (the always block thing). In VHDL the "top level" is to write independent assignment statements which all operate in parallel. Then inside a process (slightly different syntax from Verilog always blocks, it starts with process()) assignment statements are sequential code. > > To answer your question, there are two types of assignments, blocking and non-blocking. The nomenclature has never made sense to me so I don't remember which is which. Looking it up = is 'blocking' and <= is 'non-blocking'. In VHDL concurrent code always uses <=. The blocking vs. non-blocking only has meaning in sequential code since concurrent code is always executed in parallel. > > In a process <= means the assignment is done when the code pauses (usually when reaching the end of the process block). So if all assignments in a process use <= nothing is actually assigned until the end of the process and all are updated with the values on the right hand side of the assignments at the time they were encountered. The expression is evaluated and saved, but not assigned to the left hand side until the process stops. > > In a process an assignment using = in Verilog and := in VHDL is made immediately so that the value can be changed before reaching the end of the process. These are only used when you specifically need them for some reason. While they are more like what happens in non-hardware related code, HDLs mostly are coded with non-blocking assignments using <= which does not work like sequential code in other languages.
I did find a "Summary of Verilog Syntax in the meantime and, you're (obviously) right: &bull; Blocking assignment Blocking assignments are executed in the order specified in the sequential block, i.e. a blocking assignment waits for previous blocking assignment of the same time to complete before executing. register = expression; &bull; Nonblocking assignment Nonblocking assignments are executed concurrently within the sequential blocks, i.e. a nonblocking assignment executes without waiting for other nonblocking assignments of occurring at the same time to complete. register <= expression; -eoq-
> This is one of several reasons why software coders can't just "pick up" an HDL language and run with it. They actually need to learn the language and not assume it works like non-HDLs. Once they come to grips with a few differences like this, it's not so special and anyone can code in HDLs.
Yes. I'm actually a software guy who has fiddled around with hardware ever since I left college. A few weeks ago, I leafed through a book in the public library where it said "The main difference between HDL and software programming is that in HDL everything works in parallel". As I'm working in a GUI (usually I'm a command-line-junky), I was only concerned about this code block where I wanted to encapsulate this decoding. Thanks! Josef
On Thursday, February 13, 2020 at 10:49:01 AM UTC-5, Josef Moellers wrote:
> On 13.02.20 15:43, Rick C wrote: > [...] > > You appear to be programming in Verilog which I don't know so well most=
ly having programmed in VHDL. I don't know that in Verilog assignment stat= ements always have to be in a process (the always block thing). In VHDL th= e "top level" is to write independent assignment statements which all opera= te in parallel. Then inside a process (slightly different syntax from Veri= log always blocks, it starts with process()) assignment statements are sequ= ential code. =20
> >=20 > > To answer your question, there are two types of assignments, blocking a=
nd non-blocking. The nomenclature has never made sense to me so I don't re= member which is which. Looking it up =3D is 'blocking' and <=3D is 'non-bl= ocking'. In VHDL concurrent code always uses <=3D. The blocking vs. non-b= locking only has meaning in sequential code since concurrent code is always= executed in parallel.=20
> >=20 > > In a process <=3D means the assignment is done when the code pauses (us=
ually when reaching the end of the process block). So if all assignments i= n a process use <=3D nothing is actually assigned until the end of the proc= ess and all are updated with the values on the right hand side of the assig= nments at the time they were encountered. The expression is evaluated and = saved, but not assigned to the left hand side until the process stops.=20
> >=20 > > In a process an assignment using =3D in Verilog and :=3D in VHDL is mad=
e immediately so that the value can be changed before reaching the end of t= he process. These are only used when you specifically need them for some r= eason. While they are more like what happens in non-hardware related code,= HDLs mostly are coded with non-blocking assignments using <=3D which does = not work like sequential code in other languages.=20
>=20 > I did find a "Summary of Verilog Syntax in the meantime and, you're > (obviously) right: > =E2=80=A2 Blocking assignment > Blocking assignments are executed in the order specified in the > sequential block, i.e. a > blocking assignment waits for previous blocking assignment of the same > time to > complete before executing. > register =3D expression; > =E2=80=A2 Nonblocking assignment > Nonblocking assignments are executed concurrently within the sequential > blocks, i.e. a > nonblocking assignment executes without waiting for other nonblocking > assignments of > occurring at the same time to complete. > register <=3D expression; > -eoq- >=20 > > This is one of several reasons why software coders can't just "pick up"=
an HDL language and run with it. They actually need to learn the language= and not assume it works like non-HDLs. Once they come to grips with a few= differences like this, it's not so special and anyone can code in HDLs.=20
>=20 > Yes. I'm actually a software guy who has fiddled around with hardware > ever since I left college. > A few weeks ago, I leafed through a book in the public library where it > said "The main difference between HDL and software programming is that > in HDL everything works in parallel". > As I'm working in a GUI (usually I'm a command-line-junky), I was only > concerned about this code block where I wanted to encapsulate this decodi=
ng. Have you ever worked with Forth? Being a hardware guy I find the interacti= veness of Forth to be ideal for working with hardware. I can write code an= d then thoroughly test it from the command line, essentially without a comp= ile stage. More accurately, while other languages require a compiler to pr= oduce an executable image a resident Forth compiler on the target allows th= e code to be compiled during the source download with the compile being inv= isible. Or you type in your definitions to be tested interactively. =20 It's more than I can explain in a couple of paragraphs, but it's very nice = for interacting with hardware.=20 --=20 Rick C. + Get 1,000 miles of free Supercharging + Tesla referral code - https://ts.la/richard11209
On 13.02.20 17:06, Rick C wrote:

> Have you ever worked with Forth? Being a hardware guy I find the interactiveness of Forth to be ideal for working with hardware. I can write code and then thoroughly test it from the command line, essentially without a compile stage. More accurately, while other languages require a compiler to produce an executable image a resident Forth compiler on the target allows the code to be compiled during the source download with the compile being invisible. Or you type in your definitions to be tested interactively.
During a period of practical work at NPL (the "National Physical Laboratories" in Teddington (UK)) in ... ohmygodwhenwasthat ... 1979, I worked in a team that developed and built the DEMOS Multicomputer: a multicomputer with a ring as the connection infrastructure. The computers were off-the-shelf Ferranti Argus 700F while the ring hardware was developed and built at NPL (the software was mostly done by London-based "SCICON Consultancy"). I was tasked with writing test software and, unknown to me at that time, I wrote a FORTH-like runtime system where the user could construct tests using predefined primitives and build on top of that. The primitives and the tests had a simple "verb argument(s)" syntax very much like FORTH. Later, when I realized that, I bought "Threaded Interpretative Languages" and tried to get that to run on a NASCOM I Z80-based microcomputer. But, no, I never actually used FORTH. Lately, when I want to play around with hardware, I usually turn to a RasPi and control it using shell scripts and accesses to /sys/class/gpio.
> It's more than I can explain in a couple of paragraphs, but it's very nice for interacting with hardware.
From what I know about TILs in general and FORTH in particular, you're right. Maybe I should give it a try on my SB180FX whan I test the FDC-simulator. Josef
On Thu, 13 Feb 2020 16:48:57 +0100
Josef Moellers <josef.moellers@invalid.invalid> wrote:

[...]
> As I'm working in a GUI (usually I'm a command-line-junky), I was only > concerned about this code block where I wanted to encapsulate this decoding.
I've not tried the the gui from icestudio.io, but do use the command line core components of it. Email be if you'd like to see a typical Makefile, and escape the cage :-) For a front end I use a python simulator, MyHDL[1]. This, with graphic waveform display can help locate problems quickly. Your code seems to be missing an else clause to define the outputs when the peripheral chip is not being accessed. Pasted below is a test script which simulates and tests the design, generates a file for waveform viewer, and verilog. Jan Coombs -- [1] MyHDL From Python to Silicon! myhdl.org # -------------------------------------------------->% # JM_ChipIF.py (tabs converted to pairs of spaces) from myhdl import * @block def JM_ChipIF( nCS, nDACK, A0, nRD, nWR, SEL, OE, DW ): """ @always_comb def ChipIFlogic(): SEL.next = A0 if (nCS == 0) | (nDACK == 0): OE.next = not nRD DW.next = not nWR else: OE.next = 0 DW.next = 0 """ @always_comb def ChipIFlogic(): SEL.next = A0 OE.next = ( (nCS == 0) | (nDACK == 0) ) & (not nRD) DW.next = ( (nCS == 0) | (nDACK == 0) ) & (not nWR) return instances() # declare I/O nCS, nDACK, A0, nRD, nWR, SEL, OE, DW = [ Signal(bool(0)) for ii in range(8) ] TestDataBlock = [ \ # nCS, nDACK, A0, nRD, nWR, SEL, OE, DW [ 1, 1, 0, 1, 1, 0, 0, 0, ], # A0=0 [ 1, 1, 1, 1, 1, 1, 0, 0, ], # A0=1 # ... [ 1, 0, 0, 1, 1, 0, 0, 0, ], ] @block def sim_JM_ChipIF(): devUnderTest = \ JM_ChipIF( nCS, nDACK, A0, nRD, nWR, SEL, OE, DW ) @instance def tb_stim(): for ii in range(len(TestDataBlock)): testLine = TestDataBlock[ii] nCS.next = testLine[0] nDACK.next = testLine[1] A0.next = testLine[2] nRD.next = testLine[3] nWR.next = testLine[4] yield delay(10) if (SEL!=testLine[5]) \ | (OE!=testLine[6]) | (DW!=testLine[7]): print( ii, testLine) assert (SEL==testLine[5]) | (testLine[5]==None) assert (OE==testLine[6]) | (testLine[6]==None) assert (DW==testLine[7]) | (testLine[7]==None) return instances() if __name__ == '__main__': simInst = sim_JM_ChipIF() simInst.name = "mySimInst" simInst.config_sim(trace=True) simInst.run_sim(duration=1000) # convert to Verilog or VHDL convInst = \ JM_ChipIF( nCS, nDACK, A0, nRD, nWR, SEL, OE, DW ) convInst.convert(hdl='Verilog') # to see wave display: # gtkwave -S sim_JM_ChipIF.tcl sim_JM_ChipIF.vcd # -------------------------------------------------->%
On 14.02.20 12:42, Jan Coombs wrote:

> Your code seems to be missing an else clause to define the > outputs when the peripheral chip is not being accessed.
Thanks for the pointer! As for the CLI stuff: I'll come back later. Josef
On Friday, February 14, 2020 at 5:34:18 AM UTC-5, Josef Moellers wrote:
> On 13.02.20 17:06, Rick C wrote: > > > Have you ever worked with Forth? Being a hardware guy I find the interactiveness of Forth to be ideal for working with hardware. I can write code and then thoroughly test it from the command line, essentially without a compile stage. More accurately, while other languages require a compiler to produce an executable image a resident Forth compiler on the target allows the code to be compiled during the source download with the compile being invisible. Or you type in your definitions to be tested interactively. > > During a period of practical work at NPL (the "National Physical > Laboratories" in Teddington (UK)) in ... ohmygodwhenwasthat ... 1979, I > worked in a team that developed and built the DEMOS Multicomputer: a > multicomputer with a ring as the connection infrastructure. The > computers were off-the-shelf Ferranti Argus 700F while the ring hardware > was developed and built at NPL (the software was mostly done by > London-based "SCICON Consultancy"). I was tasked with writing test > software and, unknown to me at that time, I wrote a FORTH-like runtime > system where the user could construct tests using predefined primitives > and build on top of that. The primitives and the tests had a simple > "verb argument(s)" syntax very much like FORTH. > Later, when I realized that, I bought "Threaded Interpretative > Languages" and tried to get that to run on a NASCOM I Z80-based > microcomputer. > > But, no, I never actually used FORTH. Lately, when I want to play around > with hardware, I usually turn to a RasPi and control it using shell > scripts and accesses to /sys/class/gpio. > > > It's more than I can explain in a couple of paragraphs, but it's very nice for interacting with hardware. > > From what I know about TILs in general and FORTH in particular, you're > right. Maybe I should give it a try on my SB180FX whan I test the > FDC-simulator. > > Josef
You could fire up gForth on your rPi. The SB180FX appears to be a Z80 like home computer from very early days from what I can gather. If you ask on the Forth group or just use Google I am sure you will find many, many versions of Forth to play with, some ANSI (the current standard), some Forth-83 and likely FIG-Forth. No shortage of candidates. comp.lang.forth. -- Rick C. -- Get 1,000 miles of free Supercharging -- Tesla referral code - https://ts.la/richard11209
On 14.02.20 19:49, Rick C wrote:

> You could fire up gForth on your rPi. The SB180FX appears to be a Z80 like home computer from very early days from what I can gather. If you ask on the Forth group or just use Google I am sure you will find many, many versions of Forth to play with, some ANSI (the current standard), some Forth-83 and likely FIG-Forth. > > No shortage of candidates. comp.lang.forth.
Thanks for the pointers. As the Zsystem, which ist the SB180's main "OS" is upward compatible with CP/M, there is indeed no shortage of obsolete (not in the negative use of the word) software available for download. I even have a few CDs with PD software from Walnut Creek (anyone remember WC?). Josef