Site Home Archive Home FAQ Home How to search the Archive How to Navigate the Archive
Compare FPGA features and resources
Threads starting:
Authors:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
On Mon, 26 Jan 2009 09:31:01 -0800 (PST), jleslie48 wrote: >1) instead of manually coverting 'U' to x'55', how do I use a >string literal to do the job. >for instance in C, I would simply write: > >tx_data_in = 'U'; > >which is the same as the c code: > >tx_data_in = 0x55; > >my point is, I want to be able to use the ascii character instead of >the hexidecimal code. The VHDL is pretty straightforward, but clumsy because of the various type conversions you need. You can convert the character (NOT string) literal 'U' to the corresponding integer using CHARACTER'POS(). Then you need to convert the integer to std_logic_vector in the usual way. It's probably worth the trouble of creating a function: function to_slv(c: character) return std_logic_vector is begin return std_logic_vector(to_unsigned(character'pos(c)), 8)); end; (don't forget to "use ieee.numeric_std.all" as appropriate). Once you've written the function, it's easy: tx_data_in <= to_slv('U'); One small warning: historically some synthesis tools have not handled 'POS attributes, but I think you'll find it's now OK for character types in all modern tools. >2) I want a scheduler so that I can put out whole messages. I want to >be able to write on the uart, "I got it\n" In hardware? Then you'll need to count your way through the string. VHDL strings are array(1 to N) of character. If this were a testbench you could easily do variable my_message: string := "I got it" & CR & LF; ... for i in my_message'range loop SEND_A_CHARACTER(my_message(i)); end loop; But in hardware you need to maintain an explicit counter that will count its way through your string, copying the appropriate character to your Tx register at the appropriate clock cycle as indicated by some "ready" flag. Then, of course, you increment the counter ready for next time. And please note that strings do NOT get a trailing NULL character, unless you choose to add it explicitly. >------------------------------------------------------------------------------------------------- >-- LATCHING NEW TRANSMIT DATA FROM RECEIVE UART ( TX_DATA_IN >[ 7-0 ] ) >------------------------------------------------------------------------------------------------- >P7: PROCESS ( CLK_16_6MHZ, UART_RESET_BUFFER, RX_READ_BUFFER_STB, >RX_DATA_OUT( 7 DOWNTO 0 ) ) >BEGIN > IF ( CLK_16_6MHZ = '1' AND CLK_16_6MHZ'EVENT ) THEN > IF ( UART_RESET_BUFFER = '0' ) THEN > IF ( RX_READ_BUFFER_STB = '1' ) THEN > TX_DATA_IN( 7 DOWNTO 0 ) <= x"55"; > END IF; > END IF; > END IF; >END PROCESS P7; That's it; where you now do TX_DATA_IN <= x"55", instead do TX_DATA_IN <= to_slv(msg(i)); i <= i + 1; (assuming i is a signal of some integer type). But that somewhat begs the question: where do you plan to store "msg"? If it's a constant, the synthesis tool will sort it out for you; if you want it to be a variable, you'll need to think about where the storage physically lives, how to load it from some other piece of hardware etc. By the way, is TX_DATA_IN wider than 8 bits? If not, then don't waste your breath specifying (7 downto 0) on each assignment. And get into the habit of using rising_edge(C) instead of the ugly and obsolete idiom (C='1' and C'event). There used to be a time when some synthesis tools didn't understand rising_edge, but that hasn't been the case for years. Using 'event just looks archaic. -- 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.Article: 137651
On Jan 26, 1:40 pm, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com> wrote: > On Mon, 26 Jan 2009 09:31:01 -0800 (PST), jleslie48 wrote: > >1) instead of manually coverting 'U' to x'55', how do I use a > >string literal to do the job. > >for instance in C, I would simply write: > > >tx_data_in = 'U'; > > >which is the same as the c code: > > >tx_data_in = 0x55; > > >my point is, I want to be able to use the ascii character instead of > >the hexidecimal code. > > The VHDL is pretty straightforward, but clumsy because of the > various type conversions you need. You can convert the > character (NOT string) literal 'U' to the corresponding > integer using CHARACTER'POS(). Then you need to convert > the integer to std_logic_vector in the usual way. It's > probably worth the trouble of creating a function: > > function to_slv(c: character) return std_logic_vector is > begin > return std_logic_vector(to_unsigned(character'pos(c)), 8)); > end; > > (don't forget to "use ieee.numeric_std.all" as appropriate). > > Once you've written the function, it's easy: > > tx_data_in <= to_slv('U'); > > One small warning: historically some synthesis tools have > not handled 'POS attributes, but I think you'll find it's > now OK for character types in all modern tools. > > >2) I want a scheduler so that I can put out whole messages. I want to > >be able to write on the uart, "I got it\n" > > In hardware? Then you'll need to count your way through the > string. VHDL strings are array(1 to N) of character. > If this were a testbench you could easily do > > variable my_message: string := "I got it" & CR & LF; > ... > for i in my_message'range loop > SEND_A_CHARACTER(my_message(i)); > end loop; > > But in hardware you need to maintain an explicit counter > that will count its way through your string, copying > the appropriate character to your Tx register at the > appropriate clock cycle as indicated by some "ready" > flag. Then, of course, you increment the counter > ready for next time. And please note that strings > do NOT get a trailing NULL character, unless you choose > to add it explicitly. > > >------------------------------------------------------------------------------------------------- > >-- LATCHING NEW TRANSMIT DATA FROM RECEIVE UART ( TX_DATA_IN > >[ 7-0 ] ) > >------------------------------------------------------------------------------------------------- > >P7: PROCESS ( CLK_16_6MHZ, UART_RESET_BUFFER, RX_READ_BUFFER_STB, > >RX_DATA_OUT( 7 DOWNTO 0 ) ) > >BEGIN > > IF ( CLK_16_6MHZ = '1' AND CLK_16_6MHZ'EVENT ) THEN > > IF ( UART_RESET_BUFFER = '0' ) THEN > > IF ( RX_READ_BUFFER_STB = '1' ) THEN > > TX_DATA_IN( 7 DOWNTO 0 ) <= x"55"; > > END IF; > > END IF; > > END IF; > >END PROCESS P7; > > That's it; where you now do TX_DATA_IN <= x"55", > instead do > > TX_DATA_IN <= to_slv(msg(i)); > i <= i + 1; > > (assuming i is a signal of some integer type). > > But that somewhat begs the question: where do you > plan to store "msg"? If it's a constant, the synthesis > tool will sort it out for you; if you want it to be > a variable, you'll need to think about where the > storage physically lives, how to load it from some > other piece of hardware etc. > > By the way, is TX_DATA_IN wider than 8 bits? If not, > then don't waste your breath specifying (7 downto 0) > on each assignment. And get into the habit of using > rising_edge(C) instead of the ugly and obsolete > idiom (C='1' and C'event). There used to be a time > when some synthesis tools didn't understand rising_edge, > but that hasn't been the case for years. Using 'event > just looks archaic. > -- > 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. ooohhhhhh.... looks like what I want. I added to_slv to the architecture, but I get synth errors: ERROR:HDLParsers:3324 - "C:/jon/fpga_uarted_01/2009_01_26/ LOKI_New_H_Project_VHDL/Code_Versions/10 - New_Xilinx_Wrap_Data/ LOKI_Top/LOKI_Top.vhd" Line 131. IN mode Formal SIZE of to_unsigned with no default value must be associated with an actual value. ERROR:HDLParsers:854 - "C:/jon/fpga_uarted_01/2009_01_26/ LOKI_New_H_Project_VHDL/Code_Versions/10 - New_Xilinx_Wrap_Data/ LOKI_Top/LOKI_Top.vhd" Line 131. The expression can not be converted to type std_logic_vector. ERROR:HDLParsers:164 - "C:/jon/fpga_uarted_01/2009_01_26/ LOKI_New_H_Project_VHDL/Code_Versions/10 - New_Xilinx_Wrap_Data/ LOKI_Top/LOKI_Top.vhd" Line 131. parse error, unexpected CLOSEPAR, expecting SEMICOLONArticle: 137652
On Jan 26, 3:22 pm, jleslie48 <j...@jonathanleslie.com> wrote: > On Jan 26, 1:40 pm, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com> > wrote: > > > > > On Mon, 26 Jan 2009 09:31:01 -0800 (PST), jleslie48 wrote: > > >1) instead of manually coverting 'U' to x'55', how do I use a > > >string literal to do the job. > > >for instance in C, I would simply write: > > > >tx_data_in = 'U'; > > > >which is the same as the c code: > > > >tx_data_in = 0x55; > > > >my point is, I want to be able to use the ascii character instead of > > >the hexidecimal code. > > > The VHDL is pretty straightforward, but clumsy because of the > > various type conversions you need. You can convert the > > character (NOT string) literal 'U' to the corresponding > > integer using CHARACTER'POS(). Then you need to convert > > the integer to std_logic_vector in the usual way. It's > > probably worth the trouble of creating a function: > > > function to_slv(c: character) return std_logic_vector is > > begin > > return std_logic_vector(to_unsigned(character'pos(c)), 8)); > > end; > > > (don't forget to "use ieee.numeric_std.all" as appropriate). > > > Once you've written the function, it's easy: > > > tx_data_in <= to_slv('U'); > > > One small warning: historically some synthesis tools have > > not handled 'POS attributes, but I think you'll find it's > > now OK for character types in all modern tools. > > > >2) I want a scheduler so that I can put out whole messages. I want to > > >be able to write on the uart, "I got it\n" > > > In hardware? Then you'll need to count your way through the > > string. VHDL strings are array(1 to N) of character. > > If this were a testbench you could easily do > > > variable my_message: string := "I got it" & CR & LF; > > ... > > for i in my_message'range loop > > SEND_A_CHARACTER(my_message(i)); > > end loop; > > > But in hardware you need to maintain an explicit counter > > that will count its way through your string, copying > > the appropriate character to your Tx register at the > > appropriate clock cycle as indicated by some "ready" > > flag. Then, of course, you increment the counter > > ready for next time. And please note that strings > > do NOT get a trailing NULL character, unless you choose > > to add it explicitly. > > > >------------------------------------------------------------------------------------------------- > > >-- LATCHING NEW TRANSMIT DATA FROM RECEIVE UART ( TX_DATA_IN > > >[ 7-0 ] ) > > >------------------------------------------------------------------------------------------------- > > >P7: PROCESS ( CLK_16_6MHZ, UART_RESET_BUFFER, RX_READ_BUFFER_STB, > > >RX_DATA_OUT( 7 DOWNTO 0 ) ) > > >BEGIN > > > IF ( CLK_16_6MHZ = '1' AND CLK_16_6MHZ'EVENT ) THEN > > > IF ( UART_RESET_BUFFER = '0' ) THEN > > > IF ( RX_READ_BUFFER_STB = '1' ) THEN > > > TX_DATA_IN( 7 DOWNTO 0 ) <= x"55"; > > > END IF; > > > END IF; > > > END IF; > > >END PROCESS P7; > > > That's it; where you now do TX_DATA_IN <= x"55", > > instead do > > > TX_DATA_IN <= to_slv(msg(i)); > > i <= i + 1; > > > (assuming i is a signal of some integer type). > > > But that somewhat begs the question: where do you > > plan to store "msg"? If it's a constant, the synthesis > > tool will sort it out for you; if you want it to be > > a variable, you'll need to think about where the > > storage physically lives, how to load it from some > > other piece of hardware etc. > > > By the way, is TX_DATA_IN wider than 8 bits? If not, > > then don't waste your breath specifying (7 downto 0) > > on each assignment. And get into the habit of using > > rising_edge(C) instead of the ugly and obsolete > > idiom (C='1' and C'event). There used to be a time > > when some synthesis tools didn't understand rising_edge, > > but that hasn't been the case for years. Using 'event > > just looks archaic. > > -- > > 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. > > ooohhhhhh.... > > looks like what I want. > > I added to_slv to the architecture, but I get synth errors: > > ERROR:HDLParsers:3324 - "C:/jon/fpga_uarted_01/2009_01_26/ > LOKI_New_H_Project_VHDL/Code_Versions/10 - New_Xilinx_Wrap_Data/ > LOKI_Top/LOKI_Top.vhd" Line 131. IN mode Formal SIZE of to_unsigned > with no default value must be associated with an actual value. > ERROR:HDLParsers:854 - "C:/jon/fpga_uarted_01/2009_01_26/ > LOKI_New_H_Project_VHDL/Code_Versions/10 - New_Xilinx_Wrap_Data/ > LOKI_Top/LOKI_Top.vhd" Line 131. The expression can not be converted > to type std_logic_vector. > ERROR:HDLParsers:164 - "C:/jon/fpga_uarted_01/2009_01_26/ > LOKI_New_H_Project_VHDL/Code_Versions/10 - New_Xilinx_Wrap_Data/ > LOKI_Top/LOKI_Top.vhd" Line 131. parse error, unexpected CLOSEPAR, > expecting SEMICOLON never mind on this one. its a missmatched paren's problem. the line: return std_logic_vector(to_unsigned(character'pos(c)), 8)); should read: return std_logic_vector(to_unsigned(character'pos(c), 8)); I should of read the error messages more carefully.Article: 137653
On Mon, 26 Jan 2009 12:36:24 -0800 (PST), jleslie48 wrote: >the line: > return std_logic_vector(to_unsigned(character'pos(c)), 8)); > >should read: > return std_logic_vector(to_unsigned(character'pos(c), 8)); yeah, sorry. I reckon I'm entitled to an occasional mismatched parenthesis in a NG post :-) -- 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.Article: 137654
On Jan 26, 4:01 pm, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com> wrote: > On Mon, 26 Jan 2009 12:36:24 -0800 (PST), jleslie48 wrote: > >the line: > > return std_logic_vector(to_unsigned(character'pos(c)), 8)); > > >should read: > > return std_logic_vector(to_unsigned(character'pos(c), 8)); > > yeah, sorry. I reckon I'm entitled to an occasional > mismatched parenthesis in a NG post :-) > -- > 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. No worries. BTW worked like a charm. I know functions and procedures are going to be key to getting the big project done, and now the first one is written. Excellent Now to digest part 2) of your answer...Article: 137655
In and email Jonathan Leslie said: > > TX_DATA_IN( 7 DOWNTO 0 ) <=3D x"55"; > What is wrong with the way you have it written above? > > JL:: - nothing if all I want is a single character on the outbound, but t= he idea is to get to a point where I can put message strings on the outboun= d uart. My app will need message packets sent out, and making long strings= of hex code makes for a maintenance nightmare. > > having a string of > TX_DATA_IN( 7 DOWNTO 0 ) <=3D x"55"; > -- send char > TX_DATA_IN( 7 DOWNTO 0 ) <=3D x"45"; > -- send char > TX_DATA_IN( 7 DOWNTO 0 ) <=3D x"62"; > -- send char > > is gonna get real annoying I'm building up to making a > communication package where I can send out on my uart > > send_to_uart("UUT:init"); > > or > > send_to_uart("UUT:shutdown"); > > > > 1) Instead of using a test for the clock being 1 and an event, you > should use rising_edge(clock). This is a standard form and will make > the simulation match the synthesis better. > JL:: - check. thanks for semantic correction. > > > > > 2) The above should be a single process and not combined with > anything else. > JL:: Quite right, I think I misspoke. I mean that the routine needs to b= e able to handle a "parameter" (using a c term) in > place of the x"55" where some other routine establishes what exactly is g= oing to be sent on the TX line. > > > It will check for the trigger just as you have it > written. When found, it will use the character currently pointed to > by the index and increment the index. Remember that HDL describes > hardware and this is a description of the transmit holding register > and the logic controlling its timing. BTW, is this a holding > register or the transmitter data register (the one that shifts the > data out)? If the latter, you need to describe both the loading and > the shifting in one process. > > JL:: not sure what your getting at here. I don't see anything to increme= nt an index. Now as far as how the tx_data_in is used, > either as a register or transmitter data register, well that's a good que= stion. I'm gonna have to dig a little on that one. You need to *add* a counter. The only way you can access the individual characters in the string is to use an index. Thinking of this in hardware, there will be a tx shift register, a tx holding register and a character source which does not need to be a register, but can be. The two registers need to define their controls and actions in the same or different clocked processes. The character source is controlled by a counter which also needs to be defined in a clocked process. The character source can be defined in an unclocked process or in a concurrent statement. In the process it would be a case statement. In a concurrent statement it would be a selected statement, IIRC (the one that uses "with"). I can tell that you are still trying to code in C. When you refer to this as 'the routine needs to be able to handle a "parameter"' that says to me that you are thinking of a subroutine that is called by a higher routine. VHDL does not work like that really. A process is *not* a subroutine. A process defines hardware that runs separately from the other hardware in the design. Here is a way to visualize the difference. When you program in C, you would normally use a flowchart. That shows sequences of operations. When you program in an HDL, you would instead use a data flow diagram. That shows different operations on data that happen at the same time. In a flowchart, blocks can be used that represent subroutines that can be separately charted in levels. In a data flow diagram, each block is a process that runs all the time and acts on whatever data is presented to it. > The way I'm thinking is that I'm gonna need a fifo buffer where the trans= mit characters are placed and as long as that buffer is not empty the P7 pr= ocess will take a character, load it into the tx_data_in register, and send= it on its way. the fifo buffer handler will then move its pointer to the = next character in the fifo. You would only need a FIFO if you can't control the rate that characters are sent to the Xmitter. Since you are producing the characters, you can control that. Actually, the same is true for a Tx Holding register. It is only there so that a CPU can have a full character time to send the next character to the xmitter. The xmitter has timing to control the character shifting. When it is complete, the next data is loaded into the TxData register. A TxRdy signal is asserted at this time and the counter is incremented so the next character is presented. Having a poor memory for detail, I always have to use templates or look at existing code in order to write HDL. So I'll use pseudo code here, meaning don't trust my details... constant TstData : string(0 to 15) :=3D "Testing 1, 2, 3!"; signal TxCntr : integer range 0 to 15; TxNxtData <=3D TstData (TxCntr); -- Data source control, provide string data to the UART, repeat every 16 chars process SelectCntr ( clk, reset ) is begin if (reset =3D '1') then TxCntr <=3D 0; elsif ( rising_edge (clk) ) then if ( TxRdy =3D '0' ) then TxWrite <=3D '0'; else if ( TxWrite =3D '0' ) then TxWrite <=3D '1'; if ( TxCntr =3D 15 ) then TxCntr <=3D 0; else TxCntr <=3D TxCntr + 1; end if; end if; end if; end if; end process; -- This code should be replaced with your UART code process UART_Tx ( clk, reset ) is begin if (reset =3D '1') then TxCntr <=3D 0; elsif ( rising_edge (clk) ) then if ( TxBitCnt =3D 9 ) then if ( TxWrite =3D '1' ) then TxData <=3D '0' & TxNxtData; TxRdy <=3D '0'; TxBitCnt <=3D 0; elsif ( TxBitTiming =3D '1' ) then TxRdy <=3D '1'; end if; elsif ( TxBitTiming =3D '1' ) then TxData <=3D TxData ( TxData'high - 1 downto 0 ) & '1'; TxBitCnt <=3D TxBitCnt + 1; end if; end if; end process; Does this make sense? Do you see how this is different from writing C code? Rick > --- On Mon, 1/26/09, Rick Collins <gnuarm.2006@arius.com> wrote: > > > From: Rick Collins <gnuarm.2006@arius.com> > Subject: Re: RS232 Uart is working!! now to get it cleaned up. > To: jon@jonathanleslie.com > Date: Monday, January 26, 2009, 2:16 PM > > > At 01:34 PM 1/26/2009, you wrote: > > Ok finally, > > > > I've got a working UART. I initially had it monitor the receive line > > and echo back out the character that it received. > > > > I then changed it so that just sent the the letter 'U' by stuffing the > > hex code in the TX_DATA_IN buffer: > > > > TX_DATA_IN( 7 DOWNTO 0 ) <=3D x"55"; > > > > so > > > > 1) instead of manually converting 'U' to x'55', how do I use a > > string literal to do the job. > > for instance in C, I would simply write: > > > > tx_data_in =3D 'U'; > > > > which is the same as the c code: > > > > tx_data_in =3D 0x55; > > > > my point is, I want to be able to use the ascii character instead of > > the hexidecimal code. > > What is wrong with the way you have it written above? Although the > above is a character literal and not a string. A string would be > "abcd". To send that you would need a loop that sends each character > in turn. You can either put a check for TxRdy explicity in the loop > code or you can make a function that waits for TxRdy and sends one > character. Then call this function in the loop. > > Opps, I guess I was thinking of C code. You can do something > similiar in VHDL using an index to address the string. > > > 2) I want a scheduler so that I can put out whole messages. I want to > > be able to write on the uart, "I got it\n" > > > > I can see a language element in VHDL called string: > > > > constant char_sequence : string :=3D "I got it"; > > > > but I'm not sure if that is the right way to do it. in addition, I > > don't now how to send the characters of char_sequence out > > sequentially. > > > > here is my transmit process: > > > > -----------------------------------------------------------------------= -------------------------- > > -- LATCHING NEW TRANSMIT DATA FROM RECEIVE UART ( TX_DATA_IN > > [ 7-0 ] ) > > -----------------------------------------------------------------------= -------------------------- > > P7: PROCESS ( CLK_16_6MHZ, UART_RESET_BUFFER, RX_READ_BUFFER_STB, > > RX_DATA_OUT( 7 DOWNTO 0 ) ) > > BEGIN > > IF ( CLK_16_6MHZ =3D '1' AND CLK_16_6MHZ'EVENT ) THEN > > IF ( UART_RESET_BUFFER =3D '0' ) THEN > > IF ( RX_READ_BUFFER_STB =3D '1' ) THEN > > TX_DATA_IN( 7 DOWNTO 0 ) <=3D x"55"; > > END IF; > > END IF; > > END IF; > > END PROCESS P7; > > > > now the x"55"; is gonna have to change, but I imagine that this > > process will need > > to be an entity in another process that is aware of the characters "I g= ot > > it" and schedule the > > 8 characters (I, ,g,o,t, ,i,t) to go out. > > 1) Instead of using a test for the clock being 1 and an event, you > should use rising_edge(clock). This is a standard form and will make > the simulation match the synthesis better. > > 2) The above should be a single process and not combined with > anything else. It will check for the trigger just as you have it > written. When found, it will use the character currently pointed to > by the index and increment the index. Remember that HDL describes > hardware and this is a description of the transmit holding register > and the logic controlling its timing. BTW, is this a holding > register or the transmitter data register (the one that shifts the > data out)? If the latter, you need to describe both the loading and > the shifting in one process. > > RickArticle: 137656
On Jan 26, 10:28=A0am, nei...@pipstechnology.co.uk wrote: > On 25 Jan, 21:51, ales.gor...@gmail.com wrote: > > > Hi All, > > > We are developing a custom borad with Spartan 3A DSP 1800 (FG676) and > > dual x16 DDR2 SDRAMs. Address lines shoud be separated for dual memory > > controller. > > Does anybody know how to create UCF constraints for dual memory > > controller in MIG 2.3? Dual memory controllers are only supported for > > Virtex 4&5. > > > Cheers, > > > Ales > > I've had to do the exact same thing, I did it by generating 2 seperate > MIG cores, and for the second one I use the ucf from the first to > prohibit the pin placements. =A0The generation of the second MIG core > was purely to get a second ucf file. =A0It then involved a bit of manual > playing around with the VHDL to instantiate the second controller, and > then changing the signal names in the second ucf file to those for the > second controller. =A0It was a little while ago that I did this, but I > think that was what I did. > > Neill Also you want to generate your own clocks, turn off the internal DCM option when you generate the MIG cores and then you can run both cores from the same DCM's.Article: 137657
Having a poor memory for detail, I always have to use templates or look at existing code in order to write HDL. So I'll use pseudo code here, meaning don't trust my details... constant TstData : string(0 to 15) := "Testing 1, 2, 3!"; signal TxCntr : integer range 0 to 15; TxNxtData <= TstData (TxCntr); -- Data source control, provide string data to the UART, repeat every 16 chars process SelectCntr ( clk, reset ) is begin if (reset = '1') then TxCntr <= 0; elsif ( rising_edge (clk) ) then if ( TxRdy = '0' ) then TxWrite <= '0'; else if ( TxWrite = '0' ) then TxWrite <= '1'; if ( TxCntr = 15 ) then TxCntr <= 0; else TxCntr <= TxCntr + 1; end if; end if; end if; end if; end process; -- This code should be replaced with your UART code process UART_Tx ( clk, reset ) is begin if (reset = '1') then TxCntr <= 0; elsif ( rising_edge (clk) ) then if ( TxBitCnt = 9 ) then if ( TxWrite = '1' ) then TxData <= '0' & TxNxtData; TxRdy <= '0'; TxBitCnt <= 0; elsif ( TxBitTiming = '1' ) then TxRdy <= '1'; end if; elsif ( TxBitTiming = '1' ) then TxData <= TxData ( TxData'high - 1 downto 0 ) & '1'; TxBitCnt <= TxBitCnt + 1; end if; end if; end process; Does this make sense? Do you see how this is different from writing C code? Rick Yeah I'm gonna fall into that linear C programming trap a lot. And I haven't met a programmer yet worth his weight that didn't "use templates or look at existing code" Plus its been 20 years since I programmed using flowcharts, I've always worked at the mathematical algorithm level then to pseudo code, then source code. Always in a linear fashion fitting in with either C/ pascal. I think when you code threads in C is the closest you get to this environment. never liked threads ;) the SelectCntr process as you pseudo coded up, will use its clk to make the looper go through the the TstData, but the routine is going to need a governor of some sorts so that message only goes out once yes? I mean that either I have to control the clk to it or make another semaphore that turns on on reset and off on TxCntr = 15. now before I went home tonight I took a quick look at the inner workings of my Uart_tx. it seems to have two entities, a transmit_xyz, and a "water brigade" fifo. Should be interesting in the morning. - JonArticle: 137658
On Jan 26, 8:26 pm, jleslie48 <j...@jonathanleslie.com> wrote: > > Yeah I'm gonna fall into that linear C programming trap a lot. > > And I haven't met a programmer yet worth his weight that didn't > "use templates or look at existing code" > > Plus its been 20 years since I programmed using flowcharts, > I've always worked at the mathematical algorithm level then to pseudo > code, > then source code. Always in a linear fashion fitting in with either C/ > pascal. I > think when you code threads in C is the closest you get to this > environment. > never liked threads ;) The flow chart thing was just to illustrate how HDL is different from a software programming language. But you are still trying to relate software to HDL. I suggest that you just forget software and learn from scratch. > the SelectCntr process as you pseudo coded up, will use its clk > to make the looper go through the the TstData, but the routine is > going to > need a governor of some sorts so that message only goes out once yes? > I mean that either I have to control the clk to it or make another > semaphore that > turns on on reset and off on TxCntr = 15. You tell me if it goes out once or indefinitely. If you only want it to go out once, you can change it to stop when the counter reaches 16. You don't need to add another signal. Although it can be useful at times to have a separate signal from a concurrent assignment for the enable on a register. By being able to plot the enable in the simulator, it can help to find bugs. BTW, in simulation, I have always found it awkward to step the code like I was debugging software. Rather I put up waveforms as if I was debugging hardware. Stepping code can be very messy when the simulation moves between the different processes. Also, each process runs when any sensitive signal changes although it may not result in any code being run, such as on the falling edge of a register clock. Just a suggestion. I'm sure each has their own preferences. constant TstData : string(0 to 15) := "Testing 1, 2, 3!"; signal TxCntr : integer range 0 to 16; TxNxtData <= TstData (TxCntr); -- Data source control, provide string data to the UART, repeat every 16 chars process SelectCntr ( clk, reset ) is begin if (reset = '1') then TxCntr <= 0; elsif ( rising_edge (clk) ) then if ( TxRdy = '0' ) then TxWrite <= '0'; else if ( TxWrite = '0' and TxCntr <> 16 ) then TxWrite <= '1'; TxCntr <= TxCntr + 1; end if; end if; end if; end process; This will run one time and the counter will reach 16 and stop. > now before I went home tonight I took a quick look at the inner > workings of my Uart_tx. > > it seems to have two entities, a transmit_xyz, and a "water brigade" > fifo. Should be > interesting in the morning. - Jon Is this a 16550 UART? The 16xxx line of UARTs has a number of models all with backward compatibility, AFAIK. I'm not sure exactly which model first adds a FIFO rather than just a holding register (one level FIFO), but it shouldn't make a difference to your design. There will be a two signal handshake, a TxRegRdy (or TxHoldRdy) which tells the data generator that the FIFO/Tx holding register is ready to receive a new character. The data generator has to generate a write signal to put the character into the UART. It is that simple. The UART should be edge sensitive to the write signal. The handshake above will work with that. But if the handshake from the UART does not toggle on writing each Actually, if your data generator in the final design can accommodate the handshake above, you won't need the FIFO. No point in adding any complexity that is not needed. RickArticle: 137659
On 23 Jan., 21:53, jleslie48 <j...@jonathanleslie.com> wrote: > so now I see my 30ns blip of btn_down, > so the new question is why did the wizard that > made up this testbench create a 100ms delay on the > start, when that delay automatically puts me in a memory overrun > error? First of all, why did your run the testbench for 250 ms, if the tb shown is finished after less than 101 ms? 250ms is no problem for simulations in general. But it is no problem to design testbenches or designs in a way that drives every tool over its edges. Maybe you should search processes that are too often active. Arrays of std_logic_vectors are always a memory problem as each bit of slv uses typically 1-8 byte in your PC memory. Else check the memory usage of your system. If too much programs use the memory, there is nothing left for simulation. bye ThomasArticle: 137660
On Jan 25, 10:34=A0am, Antti <Antti.Luk...@googlemail.com> wrote: > Now when xilinx web is back online, well they do no have not a single > reference design for the ethernet using SFP optical links > all the demos are for the marvell SGMII phy only > > i tried to change the TEMAC PHY form SGMII to 1000base-x but > unfortunatly the system did not work after that. > well all phy registers readback 0, so maybe there is some major > problem with some clocking, and there are no other changes > required, but i kinda can not belive that xilinx has not ever > made a base1000-x based system for some of their board (ml405/ml505..) > > Antti ok, i have a reference design, but our own SFP/ethernet design still doesnt work after MPMC2-MPMC3 migration AnttiArticle: 137661
Hallo. My Spartan3 board connects a config pin (CCLK) directly to a User-IO (VCCO=3.3V). As you can imagine, this signal also goes into a serial platform flash, and is also externally tied to 2.5 V by a 4700 Ohm resistor. Now after config, I'd like to drive that signal using the User IO pin, but I'm not sure if this is safe, nor am I sure what signal-standard to use. The IO-Bank has 50 Ohm DCI-control Resistors tied to GND and VCCO, but no Vref available. Gruss Jan BrunsArticle: 137662
"Jan Bruns": > My Spartan3 board connects a config pin (CCLK) directly to > a User-IO (VCCO=3.3V). As you can imagine, this signal > also goes into a serial platform flash, and is also externally > tied to 2.5 V by a 4700 Ohm resistor. > > Now after config, I'd like to drive that signal using the > User IO pin, but I'm not sure if this is safe, nor > am I sure what signal-standard to use. > > The IO-Bank has 50 Ohm DCI-control Resistors tied > to GND and VCCO, but no Vref available. What about using trisate as high-state, never driving the line high? The Spartan3 user guide mentions specially the original Spartan3 having relatively strong pullups... Gruss Jan BrunsArticle: 137663
Hi, I have to make a PCB using BGA pinout for FPGA. What brand of software do you use ? Place Route manually or automatically ? Which plans to use and how ? For the width of the tracks ? Thanks. KappaArticle: 137664
On Mon, 26 Jan 2009 17:26:25 -0800 (PST), jleslie48 wrote: >Yeah I'm gonna fall into that linear C programming trap a lot. [...] >never liked threads ;) Time to change, if you're trying to use VHDL and hardware. >the SelectCntr process as you pseudo coded up, will use its clk >to make the looper go through the the TstData, but the routine is >going to >need a governor of some sorts so that message only goes out once yes? >I mean that either I have to control the clk to it or make another >semaphore that >turns on on reset and off on TxCntr = 15. OK, let me try to appeal to the programmer in you. Bear with me through the long-winded waffle. I'll do some hands-on practical stuff at the end. Your conventional programming paradigm is almost purely procedural (OOP changes that, but not by very much). Procedural code can be built up - composed - into bigger blocks of procedural code using well-known schemes: loops, function calls. But whatever you do in C, you end up with something *procedural*. In VHDL and any HDL, procedural code is not the only act in town. You can do all the things you do in C, BUT YOU MUST DO THEM WITHIN THE CONFINES OF A PROCESS. So we have procedural loops, we have functions and procedures, we have conditional statements, all just like C (modulo the obvious syntax differences). You compose these things into a bigger lump of procedural code, and then - and this is where the big mental shift must occur - you wrap it up as a PROCESS. As a side-effect of that, it also gets wrapped in an implied infinite loop and optionally gets a sensitivity list. From this point on, you have completely lost the power to do procedural composition. The process is, irrevocably, a concurrent block that must be composed structurally with all the other processes in your design or simulation model. Threads, whether you like them or not :-) As a matter of convenience and design organization, you then wrap a process, or a group of processes, into an entity/architecture (or a module, in Verilog). To use that entity you must instantiate it within another architecture; the instance so created is, in every meaningful sense, just a rather big process. So, let's say it just one more time: Inside a process, you write procedural code using all the sequential composition techniques you know and love. Processes, though, club together by parallel or structural composition - there is NO way to get one process or entity to "call" another. (I'm talking VHDL here. The story is a little different in Verilog, but even there I'm not wildly wrong.) (Historical note for old grumps like me: Thirty years ago, occam and CSP had this sorted out, with arbitrary sequential and parallel composition of processes at all levels of the hierarchy. But people who said "never liked threads" killed it dead. One day the wheel will turn, but not until the C programmer hegemony is smashed.) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ OK, so now let's go back to the problem faced by every programmer who tries to get to grips with HDL design: How do I get one module to call (that is, to make use of functionality in) another? First, let's think a little about how these process descriptions get mapped to hardware. You've already seen, and successfully used, the clocked process template. I'm sure that by now you understand how this works: on each clock edge, your process looks at the values of all signals and variables, and uses those values to determine the values they will have immediately after the clock edge (the "next-state" value). The whole of the process executes in zero time at the moment of the clock edge, and does NOT stop to wait for other things to happen. Consequently any state information that needs holding from one clock cycle to the next (such as "which character of the string am I sending at the moment") must have explicit storage. If you follow this approach, you have a piece of code that can be synthesized. So: you have now built your UART transmitter, and you would like to get it to send a message. As a programmer you desperately want to call a function in the UART that says "send a character". But you can't do that, because the UART is a process (OK, several processes composed into an entity). So you must use the ports on the entity to control it. By far the safest, clearest-headed way to think about this is to organize your blocks as producers or consumers of data. The UART transmitter is a consumer. It has a "ready" output of some sort, which means "on this clock edge it's OK for you to post some new data to my Tx buffer". And it has a "data valid" input of some sort, which the producer uses to say "on this clock edge, my data is valid and I want you to take it". Given this two-wire clocked handshake, we can now separate out the producer. Remember that it's a clocked process, so it must execute the whole of its process body on each and every clock. Traditionally this is coded as a state machine (I guess you use them in software too). Here's how I see the state machine shaping up: if rising_edge (clock) then -- Some outputs are asserted only in one -- state. It's easiest to establish their -- default or idle value here: UART_Tx_Data_Valid <= '0'; Ready_For_Start <= '0'; -- We don't bother to default the UART Tx data, -- because it's ignored if UART_Tx_Data_Valid is false. -- Everything is governed by the state value - -- where have we got to in the sequence? case (current_state) is when waiting_for_start => -- Tell the external world that it is OK to -- ask us to start sending. Ready_For_Start <= '1'; -- Hold until we see an external trigger. if Start_Message_Trigger = '1' then current_state <= send_a_char; msg_pointer <= 1; end if; -- otherwise remain waiting_for_start when send_a_char => -- First, check if we've fallen off the end of -- the message - ASSUMES message is null-terminated. if my_msg(msg_pointer) = NUL then current_state <= waiting_for_start; -- Otherwise, hold until the UART is ready. elsif UART_Tx_Ready = '1' then -- Prepare data for UART. UART_Tx_Data <= to_slv(my_msg(msg_pointer)); -- Drive UART data-valid strobe. UART_Tx_Data_Valid <= '1'; -- Increment ready for the next character. msg_pointer <= msg_pointer + 1; end if; when others => -- oops, current_state somehow got a bad value; -- maybe take evasive action such as resetting -- various things. end case; end if; -- clock Now, there are lots of hints here and this code is (I think) basically sound, but I've left loads of details for you to fill in - most particularly, the data declarations. But I hope it's given you a clue about how you can write completely independent consumers and producers of data, locked together by a simple clocked handshaking protocol using "ready" and "valid" signals (there are, of course, many possible ways to do the details, but that one's easy to understand). Note, too, that my "producer" here is in fact also a "consumer" in its own right; it has a start/done handshake with the next higher level producer, which I guess will take responsibility for filling-in the message data. After all, you presumably want at least some control over when and what message gets sent. Start_Message_Trigger could easily be an external push-button for the purpose of your tests. If Start_Message_Trigger is false, the state machine will stick in its waiting_for_start state. If you want to make a constant message for initial testing, you can easily null-terminate it thus: constant my_msg: string := "This is it" & NUL; Sometimes it may be better to use a string length count rather than null-termination; in that case, your end-of-message test would instead be if msg_pointer = msg_length then ... But hey - you're a programmer - you can easily see all that sort of stuff. It's the block-to-block communication and handshaking that has you confused, right? Let us know how you get on. -- 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.Article: 137665
On Jan 26, 4:28 pm, nei...@pipstechnology.co.uk wrote: > On 25 Jan, 21:51, ales.gor...@gmail.com wrote: > > > Hi All, > > > We are developing a custom borad with Spartan 3A DSP 1800 (FG676) and > > dual x16 DDR2 SDRAMs. Address lines shoud be separated for dual memory > > controller. > > Does anybody know how to create UCF constraints for dual memory > > controller in MIG 2.3? Dual memory controllers are only supported for > > Virtex 4&5. > > > Cheers, > > > Ales > > I've had to do the exact same thing, I did it by generating 2 seperate > MIG cores, and for the second one I use the ucf from the first to > prohibit the pin placements. The generation of the second MIG core > was purely to get a second ucf file. It then involved a bit of manual > playing around with the VHDL to instantiate the second controller, and > then changing the signal names in the second ucf file to those for the > second controller. It was a little while ago that I did this, but I > think that was what I did. > > Neill Thanks Neill, That's the info I need. It thought that is my only option if I do not get any additional info from Xilinx. AlesArticle: 137666
On Jan 26, 4:28 pm, nei...@pipstechnology.co.uk wrote: > On 25 Jan, 21:51, ales.gor...@gmail.com wrote: > > > Hi All, > > > We are developing a custom borad with Spartan 3A DSP 1800 (FG676) and > > dual x16 DDR2 SDRAMs. Address lines shoud be separated for dual memory > > controller. > > Does anybody know how to create UCF constraints for dual memory > > controller in MIG 2.3? Dual memory controllers are only supported for > > Virtex 4&5. > > > Cheers, > > > Ales > > I've had to do the exact same thing, I did it by generating 2 seperate > MIG cores, and for the second one I use the ucf from the first to > prohibit the pin placements. The generation of the second MIG core > was purely to get a second ucf file. It then involved a bit of manual > playing around with the VHDL to instantiate the second controller, and > then changing the signal names in the second ucf file to those for the > second controller. It was a little while ago that I did this, but I > think that was what I did. > > Neill Just one more thing: did the internal logic placement constraints overalp in your case? This can add some more manual editing to be done. Cheers, AlesArticle: 137667
On Jan 26, 11:54 pm, Gabor <ga...@alacron.com> wrote: > On Jan 26, 10:28 am, nei...@pipstechnology.co.uk wrote: > > > > > On 25 Jan, 21:51, ales.gor...@gmail.com wrote: > > > > Hi All, > > > > We are developing a custom borad with Spartan 3A DSP 1800 (FG676) and > > > dual x16 DDR2 SDRAMs. Address lines shoud be separated for dual memory > > > controller. > > > Does anybody know how to create UCF constraints for dual memory > > > controller in MIG 2.3? Dual memory controllers are only supported for > > > Virtex 4&5. > > > > Cheers, > > > > Ales > > > I've had to do the exact same thing, I did it by generating 2 seperate > > MIG cores, and for the second one I use the ucf from the first to > > prohibit the pin placements. The generation of the second MIG core > > was purely to get a second ucf file. It then involved a bit of manual > > playing around with the VHDL to instantiate the second controller, and > > then changing the signal names in the second ucf file to those for the > > second controller. It was a little while ago that I did this, but I > > think that was what I did. > > > Neill > > Also you want to generate your own clocks, turn off the internal > DCM option when you generate the MIG cores and then you can run > both cores from the same DCM's. Of course. I will use external 125MHz oscillator and let EDK to handle clocks. AlesArticle: 137668
Hello all, I am working with Alter NIOS terasic DE3 board- I've written a software for NIOS. When I run it in debug mode it look fine. When I press the on-board reset I can see in the IDE that it has entered reset mode. when I press the resume button - the SW is stuck. If I press the pause I see that the SW is stuck in a loop insited alt_tick.c --> void alt_tick(void)... Does anyone know what is the source of the alt tick? how comes that it works fine on first run and then stuck? thanks alot, GuyArticle: 137669
Guy_FPGA pisze: > Hello all, > > I am working with Alter NIOS terasic DE3 board- > > I've written a software for NIOS. When I run it in debug mode it look > fine. When I press the on-board reset I can see in the IDE that it has > entered reset mode. when I press the resume button - the SW is stuck. > If I press the pause I see that the SW is stuck in a loop insited > alt_tick.c --> void alt_tick(void)... > > Does anyone know what is the source of the alt tick? how comes that it > works fine on first run and then stuck? > > thanks alot, > > > Guy Have you tried use flash for NIOS program ? AdamArticle: 137670
On 27 Jan, 09:55, ales.gor...@gmail.com wrote: > On Jan 26, 4:28 pm, nei...@pipstechnology.co.uk wrote: > > > > > On 25 Jan, 21:51, ales.gor...@gmail.com wrote: > > > > Hi All, > > > > We are developing a custom borad with Spartan 3A DSP 1800 (FG676) and > > > dual x16 DDR2 SDRAMs. Address lines shoud be separated for dual memor= y > > > controller. > > > Does anybody know how to create UCF constraints for dual memory > > > controller in MIG 2.3? Dual memory controllers are only supported for > > > Virtex 4&5. > > > > Cheers, > > > > Ales > > > I've had to do the exact same thing, I did it by generating 2 seperate > > MIG cores, and for the second one I use the ucf from the first to > > prohibit the pin placements. =A0The generation of the second MIG core > > was purely to get a second ucf file. =A0It then involved a bit of manua= l > > playing around with the VHDL to instantiate the second controller, and > > then changing the signal names in the second ucf file to those for the > > second controller. =A0It was a little while ago that I did this, but I > > think that was what I did. > > > Neill > > Just one more thing: did the internal logic placement constraints > overalp in your case? This can add some more manual editing to be > done. > > Cheers, > > Ales Glad to help. I don't remember there being any overlapping placement constraints, I know I had to play around with the ucf a bit more later when I decided to move some of the pins around to make the board layout a bit easier. It would be nice if Xilinx would allow MIG to generate dual controllers for Spartan devices, maybe they'll do it for the Spartan 6, which is due later this year apparently. Neill.Article: 137671
On Jan 27, 3:50=A0am, secure...@gmail.com wrote: > Hi, > > I have to make a PCB using BGA pinout for FPGA. > > What brand of software do you use ? > > Place Route manually or automatically ? > > Which plans to use and how ? > > For the width of the tracks ? > > Thanks. > > Kappa I don't know what your budget is, but if you're completely inexperienced and have the money, you may want to consider using a design service. We use a local service who consistently gives us the lowest price on design projects. He uses PADS software and only autoroutes non-critical nets. I have the PADS viewer which allows me to check his design output and run off Gerber files for production. A full seat of PADS (without autorouting) starts around $5,000.00 but you can get a free evaluation copy that is limited in the size of design you can produce, if you want to play around with it first. For a hobby budget you could look at one of the on-line do-it-yourself software / fab packages like PCB123. I have used this for simple 2 and 4-layer boards. They list the design rules on their site and you can download the software there, too. The downside to this is for boards going to large-scale manufacture you have the layout in a proprietary format and get stuck with the same provider for your boards. Regards, GaborArticle: 137672
On Jan 27, 4:17 am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com> wrote: > On Mon, 26 Jan 2009 17:26:25 -0800 (PST), jleslie48 wrote: > >Yeah I'm gonna fall into that linear C programming trap a lot. > [...] > >never liked threads ;) > > Time to change, if you're trying to use VHDL and hardware. > > >the SelectCntr process as you pseudo coded up, will use its clk > >to make the looper go through the the TstData, but the routine is > >going to > >need a governor of some sorts so that message only goes out once yes? > >I mean that either I have to control the clk to it or make another > >semaphore that > >turns on on reset and off on TxCntr = 15. > > OK, let me try to appeal to the programmer in you. > Bear with me through the long-winded waffle. I'll > do some hands-on practical stuff at the end. > > Your conventional programming paradigm is almost purely > procedural (OOP changes that, but not by very much). > Procedural code can be built up - composed - into > bigger blocks of procedural code using well-known > schemes: loops, function calls. But whatever you > do in C, you end up with something *procedural*. > > In VHDL and any HDL, procedural code is not the only > act in town. You can do all the things you do in C, > BUT YOU MUST DO THEM WITHIN THE CONFINES OF A PROCESS. > So we have procedural loops, we have functions and > procedures, we have conditional statements, all just > like C (modulo the obvious syntax differences). You > compose these things into a bigger lump of procedural > code, and then - and this is where the big mental > shift must occur - you wrap it up as a PROCESS. As > a side-effect of that, it also gets wrapped in an > implied infinite loop and optionally gets a sensitivity > list. > > From this point on, you have completely lost the power > to do procedural composition. The process is, irrevocably, > a concurrent block that must be composed structurally with > all the other processes in your design or simulation model. > Threads, whether you like them or not :-) > > As a matter of convenience and design organization, you > then wrap a process, or a group of processes, into an > entity/architecture (or a module, in Verilog). To use > that entity you must instantiate it within another > architecture; the instance so created is, in every > meaningful sense, just a rather big process. > > So, let's say it just one more time: Inside a process, > you write procedural code using all the sequential > composition techniques you know and love. Processes, > though, club together by parallel or structural > composition - there is NO way to get one process or > entity to "call" another. (I'm talking VHDL here. > The story is a little different in Verilog, but > even there I'm not wildly wrong.) > > (Historical note for old grumps like me: Thirty > years ago, occam and CSP had this sorted out, with > arbitrary sequential and parallel composition of > processes at all levels of the hierarchy. But > people who said "never liked threads" killed it > dead. One day the wheel will turn, but not until > the C programmer hegemony is smashed.) > > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > OK, so now let's go back to the problem faced by > every programmer who tries to get to grips with > HDL design: How do I get one module to call (that > is, to make use of functionality in) another? > > First, let's think a little about how these > process descriptions get mapped to hardware. > You've already seen, and successfully used, the > clocked process template. I'm sure that by now > you understand how this works: on each clock > edge, your process looks at the values of all > signals and variables, and uses those values > to determine the values they will have immediately > after the clock edge (the "next-state" value). > The whole of the process executes in zero time > at the moment of the clock edge, and does NOT stop > to wait for other things to happen. Consequently > any state information that needs holding from one > clock cycle to the next (such as "which character > of the string am I sending at the moment") must > have explicit storage. If you follow this approach, > you have a piece of code that can be synthesized. > > So: you have now built your UART transmitter, and > you would like to get it to send a message. As a > programmer you desperately want to call a function > in the UART that says "send a character". But you > can't do that, because the UART is a process (OK, > several processes composed into an entity). So you > must use the ports on the entity to control it. > By far the safest, clearest-headed way to think about > this is to organize your blocks as producers or > consumers of data. The UART transmitter is a > consumer. It has a "ready" output of some sort, > which means "on this clock edge it's OK for you > to post some new data to my Tx buffer". And it has > a "data valid" input of some sort, which the producer > uses to say "on this clock edge, my data is valid > and I want you to take it". Given this two-wire > clocked handshake, we can now separate out the > producer. Remember that it's a clocked process, > so it must execute the whole of its process body > on each and every clock. Traditionally this is > coded as a state machine (I guess you use them in > software too). Here's how I see the state machine > shaping up: > > if rising_edge (clock) then > > -- Some outputs are asserted only in one > -- state. It's easiest to establish their > -- default or idle value here: > UART_Tx_Data_Valid <= '0'; > Ready_For_Start <= '0'; > -- We don't bother to default the UART Tx data, > -- because it's ignored if UART_Tx_Data_Valid is false. > > -- Everything is governed by the state value - > -- where have we got to in the sequence? > case (current_state) is > > when waiting_for_start => > -- Tell the external world that it is OK to > -- ask us to start sending. > Ready_For_Start <= '1'; > -- Hold until we see an external trigger. > if Start_Message_Trigger = '1' then > current_state <= send_a_char; > msg_pointer <= 1; > end if; -- otherwise remain waiting_for_start > > when send_a_char => > -- First, check if we've fallen off the end of > -- the message - ASSUMES message is null-terminated. > if my_msg(msg_pointer) = NUL then > current_state <= waiting_for_start; > -- Otherwise, hold until the UART is ready. > elsif UART_Tx_Ready = '1' then > -- Prepare data for UART. > UART_Tx_Data <= to_slv(my_msg(msg_pointer)); > -- Drive UART data-valid strobe. > UART_Tx_Data_Valid <= '1'; > -- Increment ready for the next character. > msg_pointer <= msg_pointer + 1; > end if; > > when others => > -- oops, current_state somehow got a bad value; > -- maybe take evasive action such as resetting > -- various things. > > end case; > > end if; -- clock > > Now, there are lots of hints here and this code is > (I think) basically sound, but I've left loads of > details for you to fill in - most particularly, the > data declarations. But I hope it's given you a clue > about how you can write completely independent consumers > and producers of data, locked together by a simple > clocked handshaking protocol using "ready" and "valid" > signals (there are, of course, many possible ways to > do the details, but that one's easy to understand). > > Note, too, that my "producer" here is in fact also > a "consumer" in its own right; it has a start/done > handshake with the next higher level producer, which > I guess will take responsibility for filling-in the > message data. After all, you presumably want at least > some control over when and what message gets sent. > Start_Message_Trigger could easily be an external > push-button for the purpose of your tests. If > Start_Message_Trigger is false, the state machine > will stick in its waiting_for_start state. > > If you want to make a constant message for initial > testing, you can easily null-terminate it thus: > > constant my_msg: string := "This is it" & NUL; > > Sometimes it may be better to use a string length > count rather than null-termination; in that case, > your end-of-message test would instead be > if msg_pointer = msg_length then ... > > But hey - you're a programmer - you can easily > see all that sort of stuff. It's the block-to-block > communication and handshaking that has you confused, > right? Let us know how you get on. > -- > 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. Rick, Jonathan, First of Jonathan, its far from long-winded waffle. You are absolutely recognizing my dilemma/misconceptions. What you are saying is absolutely correct, I've got to get it into my way of thinking, I will keep working at it. I see EE guys tremble in fear at a double nested bubble sort algorithm, something I take for granted, and here I am with the rolls reversed on something as silly as putting out the "hello world" message on a screen... Rick, I don't believe it's the 16550 Uart, I've been through so many looking for something I could use as a template, I'm bleary eyed. This is the one I got working: http://grace.evergreen.edu/dtoi/arch06w/asm/KCPSM3/ its the: UART Transmitter and REceiver Macros 8-bit,no parity, 1 stop bit Intergral 16-byte FIFO buffers by Ken Chapman Xilinx Ltd January 2003 http://grace.evergreen.edu/dtoi/arch06w/asm/KCPSM3/Docs/UART_Manual.pdf I put my hardware support engineer onto this uart version while I continued here with another uart model and low and behold he was able to actually get a Process "Generate Programming File" completed successfully for the first time in months using this template. Hence the reason I'm not totally familiar with the 'buck brigade" fifo, but if it's what I think it is, I believe my character buffer for the message is already in place. also let me make sure I've got some definitions right: a tx shift register - the storage location that is actually worked on by the TX mechanism shifting one bit at a time onto the TX wire, changing the voltages high and low at the proper time in accordance with the Baud rate. a tx holding register - this is the queue for characters to be sent out. on the completion of the tx shift register sending out the current character, the lead value in this register becomes/copies to the shift register for transmission. a character source - characters are copied to the holding register in order using an index into this "array" of 8-bit ASCII characters. I'm gonna take a few minutes to digest both of your two comments, clarify what exactly I have already, I'll be back shortly. Sincerely, JonArticle: 137673
Rick, Jonathan, First of Jonathan, its far from long-winded waffle. You are absolutely recognizing my dilemma/misconceptions. What you are saying is absolutely correct, I've got to get it into my way of thinking, I will keep working at it. I see EE guys tremble in fear at a double nested bubble sort algorithm, something I take for granted, and here I am with the rolls reversed on something as silly as putting out the "hello world" message on a screen... Rick, I don't believe it's the 16550 Uart, I've been through so many looking for something I could use as a template, I'm bleary eyed. This is the one I got working: http://grace.evergreen.edu/dtoi/arch06w/asm/KCPSM3/ its the: UART Transmitter and REceiver Macros 8-bit,no parity, 1 stop bit Intergral 16-byte FIFO buffers by Ken Chapman Xilinx Ltd January 2003 http://grace.evergreen.edu/dtoi/arch06w/asm/KCPSM3/Docs/UART_Manual.pdf I put my hardware support engineer onto this uart version while I continued here with another uart model and low and behold he was able to actually get a Process "Generate Programming File" completed successfully for the first time in months using this template. Hence the reason I'm not totally familiar with the 'buck brigade" fifo, but if it's what I think it is, I believe my character buffer for the message is already in place. also let me make sure I've got some definitions right: a tx shift register - the storage location that is actually worked on by the TX mechanism shifting one bit at a time onto the TX wire, changing the voltages high and low at the proper time in accordance with the Baud rate. a tx holding register - this is the queue for characters to be sent out. on the completion of the tx shift register sending out the current character, the lead value in this register becomes/copies to the shift register for transmission. a character source - characters are copied to the holding register in order using an index into this "array" of 8-bit ASCII characters. I'm gonna take a few minutes to digest both of your two comments, clarify what exactly I have already, I'll be back shortly. Sincerely, JonArticle: 137674
On 2009-01-27, jleslie48 <jon@jonathanleslie.com> wrote: > I've got no choice. I have a deliverable to a customer, and > failure is not an option. My project worked perfectly fine on a > DSP running C code, but the customer has dictated that It > must run in a pure FPGA environment. So now I'm on the hook > to get it to run on a FPGA. Hi, have you considered simply putting a small processor in an FPGA? If you have a large amount of C code you could use a 32-bit FPGA optimized processor like MicroBlaze if you are using Xilinx or Nios II if you are using Altera. (You will need to buy the EDK if you are using Xilinx, but it sounds like this will save you a lot of time right now so it is probably worth it.) If space is at a premium in the FPGA you could use an 8-bit processor optimized for FPGAs such as the PicoBlaze. This will allow you to create most of your project in an environment in which you are comfortable. (And as you have probably already noticed, low speed string processing is substantially easier to do in software.) There is no licensing fee for PicoBlaze as far as I know. You may still have to create some hardware to interface your processor with the outside world, but if your core algorithms are written in C I suspect that a processor is the most efficient way to get this done. If you have some performance problems you can move parts of your algorithm into hardware, but hopefully you won't need that. /Andreas
Site Home Archive Home FAQ Home How to search the Archive How to Navigate the Archive
Compare FPGA features and resources
Threads starting:
Authors:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z