![]() |
|
|
|||||||
![]() |
VHDL - Back on vhdl.. and on processes.. |
|
|
Thread Tools | Search this Thread |
|
|
#1 |
|
Hi all.
Some time ago, i found on this ng a GIANT help for my vhdl problems, so i'm here again to mess you all I'm trying (again) to create a simple module, intended to do this function: take in input a value, if this value is in a defined period output the value, else take the value in the period adding or subtracting the period value. I had 2 way yo try: do everything as a finite state machine (ARG) -> many work, many problems, bad code The other way (i thought) was trying to do the module using simple processes. That's what i wanted to do: the first process (controlled by the clock) works on the input value: if it's out of the period changes it, else simply modify a local signal named "local_signal" (ie The second process is controlled by this local signal, and on the rising edge of the signal generates the output. Obviously, nothing works so the question is: is this a valid way, or it will never work in this way? Thank you very much! Just to enjoy you, i post here my test code library IEEE; use IEEE.std_logic_1164.all; use ieee.std_logic_signed.all; use ieee.std_logic_arith.all; entity Discretizer is port( BININ : in std_logic_vector(0 to 15); BINOUT : out std_logic_vector(0 to 15) ); end Discretizer; architecture rrgen of Discretizer is constant pi : std_logic_vector(0 to 15) := "0000001100100100"; constant duepi : std_logic_vector(0 to 15) := "0000011001001000"; constant pimezzi : std_logic_vector(0 to 15) := "0000000110010010"; signal clk: bit; signal TEMP_BININ: SIGNED(BININ'range); signal create_output: bit; begin TEMP_BININ <= SIGNED(BININ); -- Data data: process( CLK ) begin if( create_output = '1' ) then create_output <= '0'; end if; if( signed(TEMP_BININ) < -signed(pi) ) then TEMP_BININ <= TEMP_BININ + signed(duepi); end if; if( signed(TEMP_BININ) > signed(pi) ) then TEMP_BININ <= TEMP_BININ - signed(duepi); end if; if( signed(TEMP_BININ) < signed(pi) and signed(TEMP_BININ) > -signed(pi) ) then create_output <= '1'; end if; end process; -- output register output_register: process( create_output ) begin if( create_output'event and create_output = '1' ) then BINOUT <= std_logic_vector( TEMP_BININ ); end if; end process; end rrgen; Massi |
|
|
|
|
#2 |
|
Junior Member
Join Date: Aug 2006
Posts: 7
|
Hello,
a few points to note: a) this problem looks purely combinational to me; if so, why do you want processes on the clk edge? its a waste of a flip flop b)i dont seem to quite understand ur problem statement here's how i interpret it: given a,b, where if (input > a AND input < b) return input else return (input + (b-a))? if thats the case, in vhdl this is simple output <= input when ((input>a)and(input<b)) else; (input + (b-a)); Jerrie85 |
|
|
|
|
|
#3 |
|
Posts: n/a
|
Massi schrieb:
> Hi all. > Some time ago, i found on this ng a GIANT help for my vhdl problems, so i'm > here again to mess you all > > I'm trying (again) to create a simple module, intended to do this function: > > take in input a value, if this value is in a defined period output the > value, else take the value in the period adding or subtracting the period > value. > > I had 2 way yo try: do everything as a finite state machine (ARG) -> many > work, many problems, bad code > The other way (i thought) was trying to do the module using simple > processes. > That's what i wanted to do: the first process (controlled by the clock) > works on the input value: if it's out of the period changes it, else simply > modify a local signal named "local_signal" (ie > The second process is controlled by this local signal, and on the rising > edge of the signal generates the output. > Obviously, nothing works so the question is: is this a valid way, or it will > never work in this way? > > Thank you very much! > Just to enjoy you, i post here my test code > Hi Massi, and we really laughed a lot Seems like you know some VHDL syntax, but have no clue what to do with it. Have you ever tried to read the error messages you get? (Do you understand them too?) If your hardware should work you should design it like hardware: Why is your clock not in the port list? Put it in there! Why is CLK in the sensitivity list of your first process, when you never use it there? Why are you assigning values to creater_output at two IFs. This can be done more clearly inside one IF. Use ELSE there. Why do you use create_output to clock the second process? Use Clock instead and make create_output as a clock_enable. What you said about FSMs: many work <= not true many problems <= not true bad code <= your fault have a nice synthesis Eilert > library IEEE; > use IEEE.std_logic_1164.all; > use ieee.std_logic_signed.all; > use ieee.std_logic_arith.all; > > entity Discretizer is > port( > BININ : in std_logic_vector(0 to 15); > BINOUT : out std_logic_vector(0 to 15) > ); > end Discretizer; > > architecture rrgen of Discretizer is > > constant pi : std_logic_vector(0 to 15) := "0000001100100100"; > constant duepi : std_logic_vector(0 to 15) := "0000011001001000"; > constant pimezzi : std_logic_vector(0 to 15) := "0000000110010010"; > > signal clk: bit; > signal TEMP_BININ: SIGNED(BININ'range); > signal create_output: bit; > > begin > > TEMP_BININ <= SIGNED(BININ); > > -- Data > data: process( CLK ) > begin > > if( create_output = '1' ) then > create_output <= '0'; > end if; > > if( signed(TEMP_BININ) < -signed(pi) ) then > TEMP_BININ <= TEMP_BININ + signed(duepi); > end if; > > if( signed(TEMP_BININ) > signed(pi) ) then > TEMP_BININ <= TEMP_BININ - signed(duepi); > end if; > > if( signed(TEMP_BININ) < signed(pi) and signed(TEMP_BININ) > > -signed(pi) ) then > create_output <= '1'; > end if; > > end process; > > -- output register > output_register: process( create_output ) > begin > > if( create_output'event and create_output = '1' ) then > BINOUT <= std_logic_vector( TEMP_BININ ); > end if; > > end process; > > end rrgen; > > backhus |
|
|
|
#4 |
|
Posts: n/a
|
backhus wrote:
> Hi Massi, > and we really laughed a lot i'm happy of that > Seems like you know some VHDL syntax, but have no clue what to do > with it. yes, basically that's the problem lol > Have you ever tried to read the error messages you get? (Do > you understand them too?) mmm... the module is compiled right, no errors.. > Why is your clock not in the port list? Put it in there! ops, thats a stupid error, i can do better > Why is CLK in the sensitivity list of your first process, when you > never use it there? Ok, that's a problem. i thought that controlling a process with clock means that every time the clock changes, che process is executed. Is this right? so why need i to use the value of clock in the process? > Why are you assigning values to creater_output at two IFs. This can be > done more clearly inside one IF. Use ELSE there. yes, that's true, the code now is written to be just clear > Why do you use create_output to clock the second process? > Use Clock instead and make create_output as a clock_enable. Ok, i simply did not understand Can you make me an example of that? thanks > What you said about FSMs: > many work <= not true speak for you > many problems <= not true speak for you > bad code <= your fault de hi ho basically, do you think i can do it in both ways? thanks so much Massi |
|
|
|
#5 |
|
Posts: n/a
|
On Tue, 22 Aug 2006 01:32:40 +0200, "Massi" <>
wrote: >Hi all. >Some time ago, i found on this ng a GIANT help for my vhdl problems, so i'm >here again to mess you all >Thank you very much! >Just to enjoy you, i post here my test code You are fighting the type system all the way with this code ... why not use it instead? >library IEEE; >use IEEE.std_logic_1164.all; --use ieee.std_logic_signed.all; --use ieee.std_logic_arith.all; use ieee.numeric_std.all; As a first step, use the standard library, not these non-standard ones. It defines usedful signed and unsigned types. >entity Discretizer is > port( > BININ : in std_logic_vector(0 to 15); > BINOUT : out std_logic_vector(0 to 15) > ); >end Discretizer; Later you may decide these ports are better "signed" or "unsigned" (unless this entity is your top-level design with ports brought out to actual pins, in which case, std_logic_vector is best) >architecture rrgen of Discretizer is > > constant pi : std_logic_vector(0 to 15) := "0000001100100100"; > constant duepi : std_logic_vector(0 to 15) := "0000011001001000"; > constant pimezzi : std_logic_vector(0 to 15) := "0000000110010010"; constant pi : signed(0 to 15) := "0000001100100100"; constant duepi : signed(pi'range) := pi(pi'low + 1 to pi'high) & '0'; constant pimezzi : signed(0 to 15) := '0' & pi(pi'low to pi'high - 1); Since you are using pi as a signed quantity throughout, why not define it as a signed type? Also, since the latter constants are related to it, if you define them from it, there is less room for errors to creep into their definition. Further, using 'range, 'high and 'low attributes keeps the latter correct even if you later change the size and value of pi because youneed greater accuracy. Incidentally I always use signed(15 downto 0), so there may be inadvertent errors in the above... > signal clk: bit; > signal TEMP_BININ: SIGNED(BININ'range); > signal create_output: bit; > >begin > >TEMP_BININ <= SIGNED(BININ); This is the ONLY necessary input type conversion - assuming BININ and BINOUT remain std_logic_vector. > > -- Data > data: process( CLK ) > begin > if( signed(TEMP_BININ) < -signed(pi) ) then > TEMP_BININ <= TEMP_BININ + signed(duepi); > end if; if( TEMP_BININ < -pi ) then TEMP_BININ <= TEMP_BININ + duepi ; etc... > if( create_output'event and create_output = '1' ) then > BINOUT <= std_logic_vector( TEMP_BININ ); and this is the only necessary output type conversion ... as above. Other problems, see other answers. But I hope this helps understand how to use the types to make life simpler... - Brian Brian Drummond |
|
|
|
#6 |
|
Posts: n/a
|
> Just to enjoy you, i post here my test code
You Enjoy Myself! * > > Why is CLK in the sensitivity list of your first process, when you > > never use it there? > > Ok, that's a problem. i thought that controlling a process with clock means > that every time the clock changes, che process is executed. Is this right? Yes. > so why need i to use the value of clock in the process? To determine what to do. Do you want to use the rising edge or falling edge, or both? (If the answer is both, good luck finding hardware that can support that). Do you want a flip-flop or a latch? (Usually you want a flip-flop). Note the difference: flip_flop: process(clk) begin if rising_edge(clk) then q <= d; end if; end process flip_flop; latch: process(gate,d) begin if gate = '1' then q <= d; end if; end process latch; > > Why do you use create_output to clock the second process? > > Use Clock instead and make create_output as a clock_enable. > > Ok, i simply did not understand > Can you make me an example of that? thanks flip_flop_enable: process(clk) begin if rising_edge(clk) then if enable = '1' then q <= d; end if; end if; end process flip_flop_enable; * sorry, couldn't resist a Phish reference in a VHDL newsgroup... http://www.phish.net/faq/syem.html jens |
|
|
|
#7 |
|
Posts: n/a
|
jens wrote:
> To determine what to do. Do you want to use the rising edge or > falling edge, or both? (If the answer is both, good luck finding > hardware that can support that). ok ok so it's enough for me the rising edge Than, i used your precious info to "fix" the module: i used the rising edge of clock in both processes, and the result is that.. nothing works like before it compiles.. yes.. but nothing else lol The strange thing (for me, lol) is this: i thought that "sequential" code BEFORE of processes had to be executed BEFORE OF PROCESSES but that's definitely false.. dunno why.. Before of the code, i'm italian and i cannot read a page in which "UFFIZI" is told "IUFFITZI" lol here is the "fixed" (lol) code What have i to do to get this piece of code working? library IEEE; use IEEE.std_logic_1164.all; use ieee.std_logic_signed.all; use ieee.std_logic_arith.all; entity Discretizer is port( CLK : in std_logic; BININ : in std_logic_vector(0 to 15); BINOUT : out std_logic_vector(0 to 15) ); end Discretizer; architecture rrgen of Discretizer is constant pi : std_logic_vector(0 to 15) := "0000001100100100"; constant duepi : std_logic_vector(0 to 15) := "0000011001001000"; constant pimezzi : std_logic_vector(0 to 15) := "0000000110010010"; signal TEMP_BININ: SIGNED(BININ'range); signal create_output: std_logic; begin TEMP_BININ <= SIGNED(BININ); create_output <= '0'; -- Data data: process( CLK ) begin if ( CLK'event and CLK = '1' ) then if( signed(TEMP_BININ) < -signed(pi) ) then TEMP_BININ <= TEMP_BININ + signed(duepi); end if; if( signed(TEMP_BININ) > signed(pi) ) then TEMP_BININ <= TEMP_BININ - signed(duepi); end if; if( signed(TEMP_BININ) < signed(pi) and signed(TEMP_BININ) > -signed(pi) ) then create_output <= '1'; end if; end if; end process; -- output register output_register: process( CLK ) begin if ( CLK'event and CLK = '1' ) then if( create_output = '1' ) then BINOUT <= std_logic_vector( TEMP_BININ ); end if; end if; end process; end rrgen; Massi |
|
|
|
#8 |
|
Posts: n/a
|
Massi schrieb:
> jens wrote: > >> To determine what to do. Do you want to use the rising edge or >> falling edge, or both? (If the answer is both, good luck finding >> hardware that can support that). > > ok ok > so it's enough for me the rising edge > > Than, i used your precious info to "fix" the module: i used the rising edge > of clock in both processes, and the result is that.. nothing works like > before > it compiles.. yes.. but nothing else lol > The strange thing (for me, lol) is this: i thought that "sequential" code > BEFORE of processes had to be executed BEFORE OF PROCESSES > but that's definitely false.. dunno why.. > > Before of the code, i'm italian and i cannot read a page in which "UFFIZI" > is told "IUFFITZI" lol > > here is the "fixed" (lol) code > What have i to do to get this piece of code working? Hi Massi, well it starts getting better. At least the clocking is ok now. But what did you do with the create_output signal... In VHDL there is no Sequential Code before processes. An assignment that is not inside a process is a concurrent assignment. That means: This line of code is a process in itself. Just without the begin-end stuff. The same is it whith condithional assignments like sig_a <= value1 when condition else value2; etc. Now, think for a moment that EVERY process is a electronic circuit. Then your Assignment create_output <= '0'; becomes a simple wire to Ground. and since this wire is connected to the signal create output, which in the first process is also used as the output of a flipflop (since it is clocked there)...gues what happens... The time your Flipflop goes to '1' = Vcc you have shortened your circuit and ist's going up in flames creating nice smoke and smells. (OK, I'm dramatizing a little, but this way it becomes more clear I hope.) Simple Rule: Drive signals from one Proccess only! like this: .... if( signed(TEMP_BININ) < signed(pi) and signed(TEMP_BININ) -signed(pi) ) then create_output <= '1'; else create_output <= '0'; end if; .... About Error Messages: Well, there may be warnings too! And it depends on the tool you are using. A simulator looks for different things than a synthesis tool. You should either turn on the "synthesisis code check" in your simulator (Modelsim has it, for instance) or use a real synthesis tool. (e.g. XST gives you warnings about sensitivity lists despite the fact that a synthesis tool doesn't care about it. Just to ceep synthesis and simulation conform.) have a nice simulation Eilert > > library IEEE; > use IEEE.std_logic_1164.all; > use ieee.std_logic_signed.all; > use ieee.std_logic_arith.all; > > entity Discretizer is > port( > CLK : in std_logic; > BININ : in std_logic_vector(0 to 15); > BINOUT : out std_logic_vector(0 to 15) > ); > end Discretizer; > > architecture rrgen of Discretizer is > > constant pi : std_logic_vector(0 to 15) := "0000001100100100"; > constant duepi : std_logic_vector(0 to 15) := "0000011001001000"; > constant pimezzi : std_logic_vector(0 to 15) := "0000000110010010"; > > signal TEMP_BININ: SIGNED(BININ'range); > signal create_output: std_logic; > > begin > > TEMP_BININ <= SIGNED(BININ); > create_output <= '0'; > > -- Data > data: process( CLK ) > begin > > if ( CLK'event and CLK = '1' ) then > > if( signed(TEMP_BININ) < -signed(pi) ) then > TEMP_BININ <= TEMP_BININ + signed(duepi); > end if; > > if( signed(TEMP_BININ) > signed(pi) ) then > TEMP_BININ <= TEMP_BININ - signed(duepi); > end if; > > if( signed(TEMP_BININ) < signed(pi) and signed(TEMP_BININ) > > -signed(pi) ) then > create_output <= '1'; > end if; > > end if; > > end process; > > -- output register > output_register: process( CLK ) > begin > > if ( CLK'event and CLK = '1' ) then > > if( create_output = '1' ) then > BINOUT <= std_logic_vector( TEMP_BININ ); > end if; > > end if; > > end process; > > end rrgen; > > backhus |
|
|
|
#9 |
|
Posts: n/a
|
backhus wrote:
> well it starts getting better. don't bet on it > In VHDL there is no Sequential Code before processes. > An assignment that is not inside a process is a concurrent assignment. > That means: This line of code is a process in itself. Just without the > begin-end stuff. That's why i like newsgroups. you learn always something new > Simple Rule: Drive signals from one Proccess only! like this: > ... > if( signed(TEMP_BININ) < signed(pi) and signed(TEMP_BININ) > -signed(pi) ) then > create_output <= '1'; > else > create_output <= '0'; > end if; > ... That's ok and is not a problem. Bue i have another problem. I have to work on the input signal, that obviously i cannot edit, so i have to use a "temp" signal inside the module. So how can i be sure that the assignment of the input signal to the temp signal will be done BEFORE of other code? > have a nice simulation Thaks, an you tell me if AT LEAST i am getting closer to the solution? Because, as always, nothing works.. The (lol) code library IEEE; use IEEE.std_logic_1164.all; use ieee.std_logic_signed.all; use ieee.std_logic_arith.all; entity Discretizer is port( read : in std_logic; CLK : in std_logic; BININ : in std_logic_vector(0 to 15); BINOUT : out std_logic_vector(0 to 15) ); end Discretizer; architecture rrgen of Discretizer is constant pi : std_logic_vector(0 to 15) := "0000001100100100"; constant duepi : std_logic_vector(0 to 15) := "0000011001001000"; constant pimezzi : std_logic_vector(0 to 15) := "0000000110010010"; signal TEMP_BININ: SIGNED(BININ'range); signal create_output: std_logic; begin -- Data data: process( CLK ) begin if ( CLK'event and CLK = '1' ) then if( read = '1' ) then TEMP_BININ <= SIGNED( BININ ); end if; if( signed(TEMP_BININ) < -signed(pi) or signed(TEMP_BININ) > signed(pi) ) then create_output <= '0'; if (signed(TEMP_BININ) < -signed(pi) ) then TEMP_BININ <= TEMP_BININ + signed(duepi); else TEMP_BININ <= TEMP_BININ - signed(duepi); end if; else create_output <= '1'; end if; end if; end process; -- output register output_register: process( CLK ) begin if ( CLK'event and CLK = '1' ) then if( create_output = '1' ) then BINOUT <= std_logic_vector( TEMP_BININ ); end if; end if; end process; end rrgen; Massi |
|
|
|
#10 |
|
Posts: n/a
|
Hi Massi,
have you seen the Movie "What About Bob" with Bill Murray? Well, then you would know what I mean when I say Babysteps. But yes... you are geting closer. > Bue i have another problem. I have to work on the input signal, that > obviously i cannot edit, so i have to use a "temp" signal inside the module. > So how can i be sure that the assignment of the input signal to the temp > signal will be done BEFORE of other code? Why is everyone (I mean you and lots of my students) always talking about TEMP variables or signals??? If you change BININ and assign it to another Signal then it is just that: Another signal. There's nothing temporary about it. So, what did you do? You put in a validation signal called "read". Good thing in the first place. Mark your valid data. When the Data is Valid (read = '1') then you assign the std_logic_vector to a signed signal. But what happens, when read = '0'? The rest of your circuit is working on the old (stored!) signed signal. So what you want is to receive some data from time to time, check and change it, and write it away. and since you are doing the discretization on the same (not very temporary) signal it changes from clock to clock and does nasty things to your output. You have a feedback here!) Now it's time to learn about (tadaa) PIPELINING. A value that is written to TEMP_BININ should not be overwritten during the Process, unless you know EXACTLY what you are doing. It's a very mighty tool for those who know how to handle it. If you change a Signal write it to another Signal. (If you like call it TEMP_BINOUT). Now you have a Pipeline: BININ -> TEMP_BININ -> TEMP_BINOUT -> BINOUT It could be coded much nicer (each assignm,ent in it's own process) to make things clearer, but anyway. This should work better. If correct I can not say. > Thaks, an you tell me if AT LEAST i am getting closer to the solution? > > Because, as always, nothing works.. Unless you get no fatal error theres always something happening in your simulation. Look at it and you will see what causes it. Or at least you can tell us what you see. have a nice simulation Eilert > > The (lol) code > > library IEEE; > use IEEE.std_logic_1164.all; > use ieee.std_logic_signed.all; > use ieee.std_logic_arith.all; > > entity Discretizer is > port( > read : in std_logic; > CLK : in std_logic; > BININ : in std_logic_vector(0 to 15); > BINOUT : out std_logic_vector(0 to 15) > ); > end Discretizer; > > architecture rrgen of Discretizer is > > constant pi : std_logic_vector(0 to 15) := "0000001100100100"; > constant duepi : std_logic_vector(0 to 15) := "0000011001001000"; > constant pimezzi : std_logic_vector(0 to 15) := "0000000110010010"; > > signal TEMP_BININ: SIGNED(BININ'range); > signal create_output: std_logic; > > begin > > -- Data > data: process( CLK ) > begin > > if ( CLK'event and CLK = '1' ) then > > if( read = '1' ) then > TEMP_BININ <= SIGNED( BININ ); > end if; > > if( signed(TEMP_BININ) < -signed(pi) or signed(TEMP_BININ) > > signed(pi) ) then > create_output <= '0'; > if (signed(TEMP_BININ) < -signed(pi) ) then > TEMP_BININ <= TEMP_BININ + signed(duepi); > else > TEMP_BININ <= TEMP_BININ - signed(duepi); > end if; > else > create_output <= '1'; > end if; > > end if; > > end process; > > -- output register > output_register: process( CLK ) > begin > > if ( CLK'event and CLK = '1' ) then > > if( create_output = '1' ) then > BINOUT <= std_logic_vector( TEMP_BININ ); > end if; > > end if; > > end process; > > end rrgen; > > backhus |
|
![]() |
| Thread Tools | Search this Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| How to execute an external software from VHDL? And how to interface VHDL with JAVA? | becool_nikks | Software | 0 | 03-06-2009 07:08 PM |
| reading mp3 file in binary format in vhdl | latheesh | General Help Related Topics | 0 | 02-05-2008 05:40 AM |
| Help on auto conversion from Matlab to vhdl on filter design | hardheart | Hardware | 0 | 12-07-2007 09:19 AM |
| ARRAY(n DOWNTO 0) OF STD_LOGIC_VECTOR(m DOWNTO 0) - VHDL | freitass | Hardware | 0 | 11-01-2007 03:44 PM |
| vhdl code | amirster | Hardware | 0 | 05-10-2007 07:28 AM |