FPGARelated.com
Forums

UART RS232 "hello world" really taking shape now.

Started by jleslie48 February 13, 2009
Just to bring those up to date, with a lot of Help from the folks
here  (JB, RC thank you! the project is taking some shape now.
Jonathan Bromley's I/O model is really a good point for the infamous
"hello world" program that I have been trying to find.  The Output
model has been expanded to this now:

JSEB_DATA_GENERATOR: entity work.data_gen
         generic map
           ( PC_bits => 9
           , the_program =>
               -- Long startup delay
               op_DELAY & 200
&                                            --2 bytes long
               -- Welcome message
               op_MESSAGE & tua(LF& "    Lprj version jb02-04-labels
added"&LF) & EOM &
               op_LABEL & 01 &
               op_MESSAGE & tua("Enter continuation character:"&LF) &
EOM &
               -- Wait for a "+" from the keyboard...
               op_WAIT_FOR_CHAR & tua("+") &
               -- and then print another message
               op_LABEL & 02 &
               op_MESSAGE & tua("abcdefghijklmnopqrstuvwxyz"&LF) & EOM
&
               -- Wait for a "-" from the keyboard
               op_WAIT_FOR_CHAR & tua("-") &
               op_MESSAGE &tua("just pressed a '-' sign!!!!"&LF) &EOM
&
               -- and then go back to the beginning! - no delay this
time.
               op_GOTOL & 02 & -- ok here is the new gotol, it will
jump to the label rather
                               -- than the array index, so the length
of the strings no longer
                               -- needs to be calculated (thank
god...)
                               --
                               -- this is a dead line now, cant get
here and GOTOL is much more.
                               -- useful.
               op_GOTO  & 29 & -- 27 is first op:2+ 2nd op:29  old
value was:2
                               -- should be 29, lets try a mistake at
26
               op_HALT
           )
         port map
           ( clock => SYSTEM_CLOCK
           , reset => initialize_data_gen   -- NOT USED in the real
hardware? - fixed, hooked to initialize_data_gen
           , timer => UART_EN_16_x_BAUD
           , tx_data  => TX_DATA_IN
           , tx_valid => tx_valid
           , tx_ready => tx_ready
           , rx_data  => RX_DATA_OUT
           , rx_valid => RX_BUFFER_DATA_PRESENT
           , rx_ready => rx_ready
           , reset_out => UART_RESET_BUFFER
           , halted => halted
           , error_cond => error_cond_main
           );


all is working, now, and I'm quite happy with this layout.  I imagine
after every op_MESSAGE I will be placing a
op_WAIT_FOR_LABEL in the future.  My UART mesages will all reside in
this packet, with the Top process changing a LABEL_TO_BE SENT byte and
zeroing it out on completion.  In this way My entire array of canned
output messages can be called up on demand.   Next up is the
LABEL_WAIT model, and then onto dynamic messaging (aka, type 5 values
into the RS232, and send the message, "the values are, x1, x2, x3, x4,
x5 and the sum is yyy").

Thanks to all on this website for their help on this journey!

Sincerely,

Jon

On Fri, 13 Feb 2009 12:24:36 -0800 (PST), jleslie48 wrote:

>expanded to this now:
> op_GOTOL & 02 & -- ok here is the new gotol, it will > -- jump to the label rather > -- than the array index, so the length > -- of the strings no longer > -- needs to be calculated
Well done for making this work - I reckon it's a good "rite of passage" and you should be able to make progress with reasonable confidence now. However, I question the motivation. Wouldn't it have been way, way easier to write a little "compiler" to do all the necessary string length and address calculations in advance, generating a piece of VHDL code (or a Xilinx memory-format file) to graft into your project, so that you could stick with the nice simple "goto address" hardware? Scanning the program to find its labels must be a non-trivial overhead.
>all is working, now, and I'm quite happy with this layout. I imagine >after every op_MESSAGE I will be placing a >op_WAIT_FOR_LABEL in the future. My UART mesages will all reside in >this packet, with the Top process changing a LABEL_TO_BE SENT byte and >zeroing it out on completion. In this way My entire array of canned >output messages can be called up on demand.
Consider a redirection table, where the addresses of the various strings are stored in a simple lookup table indexed by label number.
> then onto dynamic messaging (aka, type 5 values >into the RS232, and send the message, "the values are, >x1, x2, x3, x4, >x5 and the sum is yyy").
I still don't understand the ideological barrier to using a soft-core CPU in the FPGA. However cunning your programmable functionality, you'll soon enough encounter a problem where it's not cunning enough, but real SOFTWARE would easily do what you need. The CPU doesn't need to be big or clever - but it *does* need to be a real computing engine, which is unlikely to be true of your string-indexing machine.... Picoblaze is FREE, by almost any reasonable measure. Having such a soft-core on your FPGA doesn't call your manhood into question, nor does it inhibit your ability to do very fast stuff (far too fast for a CPU) elsewhere on the FPGA. -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK jonathan.bromley@MYCOMPANY.com http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated.
On Feb 15, 11:48=A0pm, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
> On Fri, 13 Feb 2009 12:24:36 -0800 (PST), jleslie48 wrote: > >expanded to this now: > > =A0 op_GOTOL & 02 & -- ok here is the new gotol, it will > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 -- jump to the label rather > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 -- than the array index, so the len=
gth
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 -- of the strings no longer > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 -- needs to be calculated > > Well done for making this work - I reckon it's a good > "rite of passage" and you should be able to make progress > with reasonable confidence now. > > However, I question the motivation. =A0Wouldn't it have > been way, way easier to write a little "compiler" to do > all the necessary string length and address calculations > in advance, generating a piece of VHDL code (or a Xilinx > memory-format file) to graft into your project, so that > you could stick with the nice simple "goto address" > hardware? =A0Scanning the program to find its labels > must be a non-trivial overhead. > > >all is working, now, and I'm quite happy with this layout. =A0I imagine > >after every op_MESSAGE I will be placing a > >op_WAIT_FOR_LABEL in the future. =A0My UART mesages will all reside in > >this packet, with the Top process changing a LABEL_TO_BE SENT byte and > >zeroing it out on completion. =A0In this way My entire array of canned > >output messages can be called up on demand. > > Consider a redirection table, where the addresses of > the various strings are stored in a simple lookup table > indexed by label number. > > > then onto dynamic messaging (aka, type 5 values > >into the RS232, and send the message, "the values are, > >x1, x2, x3, x4, >x5 and the sum is yyy"). > > I still don't understand the ideological barrier to using > a soft-core CPU in the FPGA. =A0However cunning your > programmable functionality, you'll soon enough encounter > a problem where it's not cunning enough, but real SOFTWARE > would easily do what you need. =A0The CPU doesn't need to be > big or clever - but it *does* need to be a real computing > engine, which is unlikely to be true of your string-indexing > machine.... =A0 > Picoblaze is FREE, by almost any reasonable measure. =A0Having > such a soft-core on your FPGA doesn't call your manhood into > question, nor does it inhibit your ability to do very fast > stuff (far too fast for a CPU) elsewhere on the FPGA. > -- > Jonathan Bromley, Consultant > > DOULOS - Developing Design Know-how > VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services > > Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK > jonathan.brom...@MYCOMPANY.comhttp://www.MYCOMPANY.com > > The contents of this message may contain personal views which > are not the views of Doulos Ltd., unless specifically stated.
Nice, that you Jonathan suggest soft-core cpu i been wondering some times already why someone does ever want to send uart data using a statemachine. for my februrary issue i did some research about FPGA vendor small soft-core cpus funnily the winner seems to be Actel CoreABC, it has most choices to finetune the core, lots of commands are optional, data width is programmable, externel bus width is progrmmable, index loop counter is optional with variable width, instruction widht is also variable (well the fixed part is 6 bits + depend on parameters), the rom generator for hard (logic tile mapped) uses "dont cares" to make the rom smaller. It is also the ONLY small soft-core that is COMPLETLY integrated with the IDE, small systems can be generated without writing single line of hdl code, just mouse click in the smart design, and enter the asm instructions in the embedded editor. uart hello ("TEST...",13,10); takes 398 actel versatiles or 206 spartan-3 slices (would be smaller if using bram rom) also nice with coreABC is the standard APB bus so can use APB peripherals:) of course picoblaze or some other core are not so much more complicated, and defenetly a recommended way todo small serial port code Antti
On Feb 15, 4:48 pm, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
> On Fri, 13 Feb 2009 12:24:36 -0800 (PST), jleslie48 wrote: > >expanded to this now: > > op_GOTOL & 02 & -- ok here is the new gotol, it will > > -- jump to the label rather > > -- than the array index, so the length > > -- of the strings no longer > > -- needs to be calculated > > Well done for making this work - I reckon it's a good > "rite of passage" and you should be able to make progress > with reasonable confidence now. > > However, I question the motivation. Wouldn't it have > been way, way easier to write a little "compiler" to do > all the necessary string length and address calculations > in advance, generating a piece of VHDL code (or a Xilinx > memory-format file) to graft into your project, so that > you could stick with the nice simple "goto address" > hardware? Scanning the program to find its labels > must be a non-trivial overhead. > > >all is working, now, and I'm quite happy with this layout. I imagine > >after every op_MESSAGE I will be placing a > >op_WAIT_FOR_LABEL in the future. My UART mesages will all reside in > >this packet, with the Top process changing a LABEL_TO_BE SENT byte and > >zeroing it out on completion. In this way My entire array of canned > >output messages can be called up on demand. > > Consider a redirection table, where the addresses of > the various strings are stored in a simple lookup table > indexed by label number. > > > then onto dynamic messaging (aka, type 5 values > >into the RS232, and send the message, "the values are, > >x1, x2, x3, x4, >x5 and the sum is yyy"). > > I still don't understand the ideological barrier to using > a soft-core CPU in the FPGA. However cunning your > programmable functionality, you'll soon enough encounter > a problem where it's not cunning enough, but real SOFTWARE > would easily do what you need. The CPU doesn't need to be > big or clever - but it *does* need to be a real computing > engine, which is unlikely to be true of your string-indexing > machine.... > Picoblaze is FREE, by almost any reasonable measure. Having > such a soft-core on your FPGA doesn't call your manhood into > question, nor does it inhibit your ability to do very fast > stuff (far too fast for a CPU) elsewhere on the FPGA. > -- > Jonathan Bromley, Consultant > > DOULOS - Developing Design Know-how > VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services > > Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK > jonathan.brom...@MYCOMPANY.comhttp://www.MYCOMPANY.com > > The contents of this message may contain personal views which > are not the views of Doulos Ltd., unless specifically stated.
John, Antti, At this stage, this is mostly an exercise in controlling mechanisms in a FPGA using VHDL. I'm sure its not the best and I'm sure in the future I'll be exploring more efficient ways of doing things, but for now, the hammer and chisel are what I need to learn. "Consider a redirection table, where the addresses of the various strings are stored in a simple lookup table indexed by label number. " That is exactly what I did, I think. Actually I had a question about that. I used your [JB's] function CONTENTS as a template and created function FIND_LABEL: --------------------------------------------------------------------- function find_label(pgm: t_ubyte_array) return t_lbl is constant p: t_ubyte_array (0 to pgm'length-1) := pgm; variable it: t_lbl; begin it := (others => 0); for i in 0 to (p'length-2) loop if (p(i)= op_label) then it(p(i+1)) := i; end if; end loop; return it; end; -- The ROM contents, initialized from the generic constant the_rom: t_rom := contents(the_program); constant the_label: t_lbl := find_label(the_program); ... when op_LABEL => PC <= PC+1; -- skip the label data lbl gen_state <= new_PC; when op_GOTO => PC <= rom_data; gen_state <= new_PC; when op_GOTOL => PC <= the_label(rom_data); --lbl gen_state <= new_PC; when op_HALT => --------------------------------------------------------------------- My question is, when (to use the term loosely) does this function run (again using the term loosely) It seems to me that it only "needs" to establish the arrays once, but I know the process is alive always, is it constantly remaking the storage locations the_rom and the_label over and over? It probably doesn't make a difference, I'm thinking the conveyor-belt linear system of cpu programming. In that case you don't want to keep parsing the same string over and over, but in the FPGA world it doesn't make a difference. "Wouldn't it have been way, way easier to write a little "compiler" to do all the necessary string length and address calculations in advance, generating a piece of VHDL code (or a Xilinx memory-format file) to graft into your project, so that you could stick with the nice simple "goto address" hardware? Scanning the program to find its labels must be a non-trivial overhead. " Again, I'm pretty sure that is what I did. I'm not sure what you mean by nice simple "goto address" to me the simplest way was to drop a marker at the beginning of whatever message I want and reference that marker with the GOTOL command. In this way, all the string and address calcuations ARE calculated as you suggested. Sincerely, Jon
On Mon, 16 Feb 2009 05:21:37 -0800 (PST), jleslie48 wrote:

>At this stage, this is mostly an exercise in controlling >mechanisms in a FPGA using VHDL.... the hammer and >chisel are what I need to learn.
Fair enough. Good to try it on an example that has reasonably interesting control flow, but where the data manipulation is trivial.
>"Consider a redirection table, where the addresses of >the various strings are stored in a simple lookup table >indexed by label number. " > >That is exactly what I did, I think. Actually I had a question about >that. >I used your [JB's] function CONTENTS as a template and created >function FIND_LABEL: > >--------------------------------------------------------------------- > function find_label(pgm: t_ubyte_array) return t_lbl is > constant p: t_ubyte_array (0 to pgm'length-1) := pgm; > variable it: t_lbl; > begin > it := (others => 0); > for i in 0 to (p'length-2) loop > if (p(i)= op_label) then > it(p(i+1)) := i; > end if; > end loop; > return it; > end;
Very nice. Give the synth tool lots of work to do. THAT is the payoff you get when software folk have struggled to understand how this works - they can easily see how to get some real mileage out of the compiler. I wish more of the design community were prepared to do the same :-)
> -- The ROM contents, initialized from the generic > constant the_rom: t_rom := contents(the_program); > constant the_label: t_lbl := find_label(the_program);
OK, you've used the function to initialize a constant (at the architecture or process level) so it gets executed at ELABORATION time - the COMPILER takes the hit, the hardware just sees a lookup table (ROM). You have written my "string address compiler" in VHDL! Now to add some compiler error checks (duplicate label definitions?) - consider using a VHDL assert statement for that: if (p(i)= op_label) then assert it(p(i+1)) = 0 -- Nothing there yet, I hope report "Duplicate label " & integer'image(p(i+1)) & " at address " & integer'image(i+1) severity FAILURE; it(p(i+1)) := i; end if; will cause synthesis to fail on that error. By contrast, a constant declared in a function or procedure is evaluated afresh every time the subprogram is called, and therefore it typically costs the HARDWARE some effort (unless the compiler can see that it is truly invariant, and optimize the function away).
>My question is, when (to use the term loosely) does this function >run (again using the term loosely) It seems to me that it only >"needs" to establish the arrays once, but I know the process is >alive always, is it constantly remaking the storage locations >the_rom and the_label over and over?
See above. When considering VHDL you need to be very clear about the idea of ELABORATION - the last part of compilation, very roughly analogous to linking in C. At elaboration time, the instance hierarchy is constructed top-down. Constants are given their values, and then possibly used to determine the structure of child instances. Elaboration determines the hardware's structure, but does not represent activity within the hardware itself. Processes, on the other hand, execute in response to signal-change events and therefore represent real hardware activity.
>It probably doesn't make a difference
It most certainly does! Remember that any piece of VHDL that does not contain a "wait" statement must execute in zero simulated time, and therefore must represent the behaviour of a piece of combinational logic in hardware. What nightmare hardware would be needed to determine the set of label addresses as a boolean-logic function of the input string? Aaaaargh!
> I'm thinking the conveyor-belt >linear system of cpu programming. In that case you don't want to keep >parsing the same string over and over, but in the FPGA world it >doesn't make a difference.
Eh?????!!!!! See above....
>"Wouldn't it have >been way, way easier to write a little "compiler" to do >all the necessary string length and address calculations >in advance, generating a piece of VHDL code (or a Xilinx >memory-format file) to graft into your project, so that >you could stick with the nice simple "goto address" >hardware? Scanning the program to find its labels >must be a non-trivial overhead. " > >Again, I'm pretty sure that is what I did. I'm not >sure what you mean by nice simple "goto address" >to me the simplest way was to drop a marker at >the beginning of whatever message I want and >reference that marker with the GOTOL command. >In this way, all the string and address calcuations >ARE calculated as you suggested.
More or less, but you still need to access your indirection table once per jump, whereas you *could* precalculate the jump addresses and avoid the table lookup. Imagine this "program": MSG "Hello" GOTO LabelA LABEL LabelB MSG "At B" HALT LABEL LabelA MSG "At A" GOTO LabelB Now, I could imagine compiling this into the "machine code" address code 0 MSG 1 "Hello" 6 EOM 7 GOTO 16 // GOTO LabelA 9 MSG // LabelB is at address 9 10 "At B" 14 EOM 15 HALT 16 MSG // LabelA is at address 16 17 "At A" 21 EOM 22 GOTO 9 // GOTO LabelB No label lookup table is now required, right? All the "compilation" work was done by the synthesis tool, at elaboration time, leaving the minimum of run-time hardware activity and therefore saving hardware and allowing for higher clock rates. Maybe you've already done this and/or more, so please ignore me if I'm telling you stuff you already know. Enjoy -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK jonathan.bromley@MYCOMPANY.com http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated.
On Feb 16, 9:36 am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
> On Mon, 16 Feb 2009 05:21:37 -0800 (PST), jleslie48 wrote: > >At this stage, this is mostly an exercise in controlling > >mechanisms in a FPGA using VHDL.... the hammer and > >chisel are what I need to learn. > > Fair enough. Good to try it on an example that has > reasonably interesting control flow, but where the > data manipulation is trivial. > > > > >"Consider a redirection table, where the addresses of > >the various strings are stored in a simple lookup table > >indexed by label number. " > > >That is exactly what I did, I think. Actually I had a question about > >that. > >I used your [JB's] function CONTENTS as a template and created > >function FIND_LABEL: > > >--------------------------------------------------------------------- > > function find_label(pgm: t_ubyte_array) return t_lbl is > > constant p: t_ubyte_array (0 to pgm'length-1) := pgm; > > variable it: t_lbl; > > begin > > it := (others => 0); > > for i in 0 to (p'length-2) loop > > if (p(i)= op_label) then > > it(p(i+1)) := i; > > end if; > > end loop; > > return it; > > end; > > Very nice. Give the synth tool lots of work to do. > THAT is the payoff you get when software folk have > struggled to understand how this works - they can > easily see how to get some real mileage out of the > compiler. I wish more of the design community were > prepared to do the same :-) > > > -- The ROM contents, initialized from the generic > > constant the_rom: t_rom := contents(the_program); > > constant the_label: t_lbl := find_label(the_program); > > OK, you've used the function to initialize a constant > (at the architecture or process level) so it gets > executed at ELABORATION time - the COMPILER takes > the hit, the hardware just sees a lookup table (ROM). > You have written my "string address compiler" in VHDL! > Now to add some compiler error checks (duplicate > label definitions?) - consider using a VHDL assert > statement for that: > > if (p(i)= op_label) then > assert it(p(i+1)) = 0 -- Nothing there yet, I hope > report "Duplicate label " & integer'image(p(i+1)) > & " at address " & integer'image(i+1) > severity FAILURE; > it(p(i+1)) := i; > end if; > > will cause synthesis to fail on that error. > > By contrast, a constant declared in a function > or procedure is evaluated afresh every time the > subprogram is called, and therefore it typically > costs the HARDWARE some effort (unless the compiler > can see that it is truly invariant, and optimize > the function away). > > >My question is, when (to use the term loosely) does this function > >run (again using the term loosely) It seems to me that it only > >"needs" to establish the arrays once, but I know the process is > >alive always, is it constantly remaking the storage locations > >the_rom and the_label over and over? > > See above. When considering VHDL you need to be very clear > about the idea of ELABORATION - the last part of compilation, > very roughly analogous to linking in C. At elaboration time, > the instance hierarchy is constructed top-down. Constants > are given their values, and then possibly used to determine > the structure of child instances. Elaboration determines > the hardware's structure, but does not represent activity > within the hardware itself. > > Processes, on the other hand, execute in response to > signal-change events and therefore represent real > hardware activity. > > >It probably doesn't make a difference > > It most certainly does! Remember that any piece of VHDL > that does not contain a "wait" statement must execute in > zero simulated time, and therefore must represent the > behaviour of a piece of combinational logic in hardware. > > What nightmare hardware would be needed to determine the > set of label addresses as a boolean-logic function of the > input string? Aaaaargh! > > > I'm thinking the conveyor-belt > >linear system of cpu programming. In that case you don't want to keep > >parsing the same string over and over, but in the FPGA world it > >doesn't make a difference. > > Eh?????!!!!! See above.... > > > > >"Wouldn't it have > >been way, way easier to write a little "compiler" to do > >all the necessary string length and address calculations > >in advance, generating a piece of VHDL code (or a Xilinx > >memory-format file) to graft into your project, so that > >you could stick with the nice simple "goto address" > >hardware? Scanning the program to find its labels > >must be a non-trivial overhead. " > > >Again, I'm pretty sure that is what I did. I'm not > >sure what you mean by nice simple "goto address" > >to me the simplest way was to drop a marker at > >the beginning of whatever message I want and > >reference that marker with the GOTOL command. > >In this way, all the string and address calcuations > >ARE calculated as you suggested. > > More or less, but you still need to access your > indirection table once per jump, whereas you *could* > precalculate the jump addresses and avoid the table > lookup. Imagine this "program": > > MSG "Hello" > GOTO LabelA > LABEL LabelB > MSG "At B" > HALT > LABEL LabelA > MSG "At A" > GOTO LabelB > > Now, I could imagine compiling this into the "machine code" > > address code > 0 MSG > 1 "Hello" > 6 EOM > 7 GOTO 16 // GOTO LabelA > 9 MSG // LabelB is at address 9 > 10 "At B" > 14 EOM > 15 HALT > 16 MSG // LabelA is at address 16 > 17 "At A" > 21 EOM > 22 GOTO 9 // GOTO LabelB > > No label lookup table is now required, right? > All the "compilation" work was done by the synthesis > tool, at elaboration time, leaving the minimum of > run-time hardware activity and therefore saving > hardware and allowing for higher clock rates. > > Maybe you've already done this and/or more, so please > ignore me if I'm telling you stuff you already know. > > Enjoy > -- > Jonathan Bromley, Consultant > > DOULOS - Developing Design Know-how > VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services > > Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK > jonathan.brom...@MYCOMPANY.comhttp://www.MYCOMPANY.com > > The contents of this message may contain personal views which > are not the views of Doulos Ltd., unless specifically stated.
Yes, these are the ideas I've been formulating all weekend long. we are [finally] moving to the same page. "Now to add some compiler error checks (duplicate label definitions?) - consider using a VHDL assert " Most definitely. My code is far from bullet-proof. My first self-inflicted wound was this: -- A LABEL is a marker, a noop, but used for the GOTOL lbl constant op_LABEL : t_ubyte := 76; -- 'L' and since my label parser was stupid, ANY 'L' character, including the ones as part of the data of an op_MESSAGE generated label lookups, and as the character after a 'L' character did not necessarily fit into the boundaries of my lookup table, this crashed big time. Now the correct course of action would be to actually define a grammar for the "the_program" command set, with context specifiers and full language specfications. for example: the_program ==> <set_of_comands> <set_of_commands> ==> [<simple_command> [simple_command_tail]] <simple_command_tail> ==> [& <simple_command>] <simple_command> ==> [ op_HALT | op_DELAY <op_delay_data> | ... etc. however, I just took a tactical approach; made sure that my op_LABEL tag was in a disjoint set from any possible data value. Simply put, I made sure that the op_LABEL command would never be in any part of the program in another context by changing the constant to: -- A LABEL is a marker, a noop, but used for the GOTOL lbl constant op_LABEL : t_ubyte := 176; --NON standard ascii char. the value 176 ~should~ never be in an ascii string in the_program. Now if an application programmer should want a delay of of 176 units, well then I'm gonna slap him about the head and neck... Of course this is a cheat, but it will work with just being a little careful. "Imagine this "program": MSG "Hello" GOTO LabelA LABEL LabelB MSG "At B" HALT LABEL LabelA MSG "At A" GOTO LabelB " Not exactly what I had imagined, I had imagined it this way: LABEL xx1: MSG "the quick brown fox" WGOTOL <noop> LABEL xx2: MSG "Mary had a little lamb" WGOTOL <noop> ... LABEL xxn: MSG "Its the end of the world as we know it." WGOTOL <noop> where WGOTOL is similar to your op_WAIT_FOR_CHAR only instead of getting its data fields from the next byte and the rx_data line, the entity would have a new "input" of the print_target_label, which would have the value of xx1, xx2, ... xxn and thus send the MSG out the uart and then spin waiting for the next update to print_target_label. Should have that done shortly. Sincerely, Jon sincerely, Jon
On Mon, 16 Feb 2009 08:51:55 -0800 (PST), jleslie48 wrote:

> and since my label parser was stupid, ANY 'L' character, > including the ones as part of the data of an op_MESSAGE > generated label lookups
Tee hee. Betcha you would never have done anything so dumb when working on your home territory :-) Be aware that the Xilinx blockRAMs natively have 9-bit data width. So you could rather easily use the MSB as an "opcode" or other out-of-band marker, simplifying this sort of stuff no end, and still preserve 8 data bits in the message literals. -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK jonathan.bromley@MYCOMPANY.com http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated.