- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello everybody I'm new in VHDL and I'm doing a project with DE2 board
In the project I need to build a robot. My first step was to design a ASM and from that to take out the FSM which i did (hopefully I did it good enough) The second step is to check one of my ASM and I choose my engine control ASM I wrote a program in VHDL using quartus and burn it into my board Instead of using the motors from the beginnig the idea was to used the board's led using a PWM generator that will create a "running led" effect for a curtain direction and in change it in a push of a button but it didn't work. Can anybody tell me what I did wrong? I think it's in the pin assignmentLink Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The code:
library IEEE; use IEEE.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; Entity Pwm is Port ( Rst : In std_logic; Clk : In std_logic; s : In std_logic; Enable : in std_logic; Led : buffer std_logic_vector (7 downto 0); Pwm : Out std_logic ); attribute altera_chip_pin_lc : string; attribute altera_chip_pin_lc of clk : signal is "@N2"; attribute altera_chip_pin_lc of rst : signal is "@G26"; attribute altera_chip_pin_lc of Led : signal is "@AE23, @AF23, @AB21, @AC22, @AD22, @AD23, @AD21"; attribute altera_chip_pin_lc of s : signal is "@N25"; attribute altera_chip_pin_lc of Enable : signal is "@N26"; end entity Pwm; Architecture arc_Pwm of Pwm is signal Counter : std_logic_vector (16 downto 0); signal DC : std_logic_vector (16 downto 0); begin PwmReg: process (Clk,Rst,s) begin if (Rst='1') then Counter <= (others=>'0'); Pwm <= '0'; Led <= (others=>'0'); DC <= conv_std_logic_vector(32678,17); --duty cycle 50% elsif rising_edge(Clk) then if (Enable='1') then if (Counter = 50000) then Counter <= (others => '0'); elsif (Counter < DC) then Counter <= Counter + 1; Pwm <= '1'; if (s = '1') then led <= Led + 1; if(Led = "11111111") then Led <= (others=>'0'); end if; else led <= Led - 1; if(Led = "00000000") then Led <= (others=>'1'); end if; end if; else Counter <= Counter + 1; Pwm <= '0'; end if; else Pwm <= '0'; end if; end if; end process PwmReg; end architecture arc_Pwm;- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi rotemkim,
I am changing the name of your thread title to something more specific to your topic of discussion. Also I'm moving it to the General Altera Discussion category. The "Altera Forum Website Related" category is for questions about the forum website or its use, not the use of devices or tools from Altera. For help with your problem, it would be easier for others to give you advice if you point out some debug steps you've taken. Have you simulated the VHDL code to see if it behaves as you expect? The pinout check is also a good start, but checking the code in simulation is better start. You may want to add a sanity check output pin that drives an LED on the board. Divide your input clock to a slow speed <= a few Hz and assign it to the output pin that drives the LED. Start small and work your way back to full design functionality.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
your right I do need to simulate the code first...
I wrote a tb for the code but i dont see any waveform way?
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
--use std.textio.all;
--use ieee.std_logic_textio.all;
------------------------------------------------------------------------------
entity tb_pwm is
end entity tb_pwm;
------------------------------------------------------------------------------
architecture arc_tb_pwm of tb_pwm is
signal Clk : std_logic := '0'; --
signal Rst : std_logic := '0'; --
signal Sw : std_logic_vector (2 downto 0):= "000"; --
signal Enable : std_logic := '0'; --
signal Pwm : std_logic; --
signal Led : std_logic_vector(7 downto 0); --
begin
test : entity work.pwm
port map (
Clk => Clk,
Rst => Rst,
Enable => Enable,
Sw => Sw,
Pwm => Pwm,
Led => Led );
Clk <= not Clk after 10 ns;
Rst <= '1' after 20 ns;
process
begin
wait until Rst = '1';
wait until rising_edge(Clk);
Enable <= '1';
wait until rising_edge(clk);
Sw(0) <= '1';
Sw(1) <= '0';
Sw(2) <= '0';
wait for 100ms;
wait until rising_edge(clk);
Sw(0) <= '0';
Sw(1) <= '1';
Sw(2) <= '0';
wait for 100ms;
wait until rising_edge(clk);
Sw(0) <= '0';
Sw(1) <= '0';
Sw(2) <= '1';
wait for 100ms;
wait until rising_edge(clk);
Enable <= '0';
wait for 100ms;
wait until rising_edge(clk);
Rst <='0';
wait for 100ms;
end process;
end architecture arc_tb_pwm;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The testbench doesnt match the PWM code you posted. In your PWM code, there is no SW bus.
One other things: When you use a std_logic_vector as a counter (I highly recommend you dont, use the numeric_std library instead of std_logic_arith/unsigned) you dont need to reset it if it gets to max. It will roll over if you get to all ones and roll under if you get to all zeros. You only have to check the value if LED was an integer rather than std_logic_vector.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your right I changed the code a little.
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
Entity Pwm is
Port ( Rst : In std_logic;
Clk : In std_logic;
Sw : In std_logic_vector (2 downto 0);
Enable : in std_logic;
Led : out std_logic_vector (7 downto 0);
Pwm : Out std_logic);
attribute altera_chip_pin_lc: string;
attribute altera_chip_pin_lc of Clk : signal is "@N2";
attribute altera_chip_pin_lc of Rst : signal is "@G26";
attribute altera_chip_pin_lc of Led : signal is "@AE23, @AF23, @AB21, @AC22, @AD22, @AD23, @AD21, @AC21";
attribute altera_chip_pin_lc of Sw : signal is "@N25,@N26, @P25";
attribute altera_chip_pin_lc of Enable: signal is "@AE14";
end entity Pwm;
Architecture arc_Pwm of Pwm is
signal Counter : std_logic_vector (16 downto 0);
signal DC : std_logic_vector (16 downto 0);
signal Rd_led : std_logic_vector (7 downto 0);
begin
PwmReg: process (Clk,Rst,Sw)
begin
if (Rst='1') then
Counter <= (others=>'0');
Pwm <='0';
Led <= (others=>'0');
Rd_led <= (others=>'0');
DC <= conv_std_logic_vector(32678,17); --duty cycle 50%
elsif rising_edge(Clk) then
if (Enable='1') then
if (Counter = 50000) then
Counter <= (others => '0');
if (Sw(0) = '1') and (Sw(1) = '0') and (Sw(2) = '0') then
Rd_led <= Rd_led + 1;
elsif (Sw(0) = '0') and (Sw(1) = '1') and (Sw(2) = '0') then
Rd_led <= Rd_led - 1;
end if;
Led <= Rd_led;
elsif (Counter < DC) then
Counter <= Counter + 1;
Pwm <= '1';
else
Counter <= Counter + 1;
Pwm <= '0';
end if;
else
Pwm <= '0';
end if;
end if;
end process PwmReg;
end architecture arc_Pwm;
I am don't know what numeric std library does can you clarify please, and why is it better to use rather then std_logic in general and specific in this code
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The problem is your reset it driven outside and inside the process, leading to rst beign 'X', and none of the internal counters get initialised to 0. Either remove the rst <= after 20ns; line or Rst <= '0' inside the process.
Signals can only be driven from one place. Secondly - are you sure you meant wait for 100ms? that is 10 million clocks with the clock period you have chosen. thirdly, you are holding the design in reset for the whole simulation. numeric_std is the official IEEE standard library. std_logic_arith/unsigned are not a real standard, but they allow you to do maths on std_logic_vectors. std_logic_vectors were NOT meant to represent an integer, just a collection of bits. numeric_std contains an unsigned and signed type that do represent numbers. you cannot use numeric_std and std_logic_arith in the same file as they contain clashes.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I see the Rst problem now and it was supposeto be ns and ms... but still no waves?
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
--use std.textio.all;
--use ieee.std_logic_textio.all;
------------------------------------------------------------------------------
entity tb_pwm is
end entity tb_pwm;
------------------------------------------------------------------------------
architecture arc_tb_pwm of tb_pwm is
signal Clk : std_logic := '0'; --
signal Rst : std_logic := '0'; --
signal Sw : std_logic_vector (2 downto 0):= "000"; --
signal Enable : std_logic := '0'; --
signal Pwm : std_logic; --
signal Led : std_logic_vector(7 downto 0); --
begin
test : entity work.pwm
port map (
Clk => Clk,
Rst => Rst,
Enable => Enable,
Sw => Sw,
Pwm => Pwm,
Led => Led );
Clk <= not Clk after 10 ns;
process
begin
wait until rising_edge(Clk);
Enable <= '1';
wait until rising_edge(clk);
Sw(0) <= '1';
Sw(1) <= '0';
Sw(2) <= '0';
wait until rising_edge(clk);
Sw(0) <= '0';
Sw(1) <= '1';
Sw(2) <= '0';
wait for 0.1us;
wait until rising_edge(clk);
Sw(0) <= '0';
Sw(1) <= '0';
Sw(2) <= '1';
wait for 0.1us;
wait until rising_edge(clk);
Enable <= '0';
wait for 0.1us;
wait until rising_edge(clk);
wait for 0.1us;
Rst<= '0';
end process;
end architecture arc_tb_pwm;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Maybe you do mean ms. The rd_led counter only increments once every 50000 clock cycles (thats once every 500 us) so 1ms increments the counter twice
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Plus also the LED output lags the rd counter by 50000 clocks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I wanted that the led will light in 1khz so I could see them.
so if DE2 board have 50Mhz clock I need to count to 50000. taking that into account if every cycle I raise the output Led only once it means that the led change once per 0.5ms that means twice in 1khz cycle just like you said and what I wanted it to do. once and let say I want it to run at least 50 times so I need 50ms delay so far I hope I got it right. I don't know what you mean when you say that the Led lag the rd_led they update together they are in the same IF Statement suppose to be any way that who I see it . if the code is good at least reasonable enough to work maybe I just dont know who to run the sim and a guide will help?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- I don't know what you mean when you say that the Led lag the rd_led they update together they are in the same IF Statement suppose to be any way that who I see it . --- Quote End --- Because you assign LED to rd_LED, LED takes the old value of rd_LED. Signals are not updated immediatly like variables, they are updated when a process suspends. so whith this code in a clocked process: b <= a; c <= b; this is what happens:
clk _|-|_|-|_|-|_|-|_|-|_|
a 0 1 2 3 4 5
b U 0 1 2 3 4
c U U 0 1 2 3
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
your right I should have know that...
that kind of relate to a another problem I notice, if I have a lag and I want to get ride of it I need to change Rd_Led to a variable but then his value want be save after he loop right? so what can I do?. second problem is about DC it's a lacth and can't work in a real board. I need to change it to a constant, but I want it to be more general code so I'll change it to a generic , were and who do I create a generic (entity, architecture ..)?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
To make LED connect to RD_LED, just assign it outside of a process. Or if you want to make it a variable, just assign LED above if counter = 50000 then.., and asign RD_led (as a variable) where it is now. Variables can store values between clocks if you put things in the right order.
For DC, because it is set a value and nothing else, Quartus will probably just assume it is a constant. But making it a generic might be a good idea. Generics are created like ports, in the generic section:
entity my_ent is
generic (
DC : integer;
);
port (
);
end entity my_ent;
Then when you do the instantiation, you give it a value.
my_inst : entity work.my_ent
generic map (
DC => 32678,
)
port map (
...
);
Inside your entity, you just treat generics like constants.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
wow thanks,
That should be very helpful I have tests coming up this week I'll let you know who I managed to fix the code later on- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hii again
the code has changed (add generic and a constant) and I am using the modelsim now insted of the active hdl but I still don't see any waves in the simulation :mad:
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
Entity Pwm is
generic (
DC : time:=1 ms;
clock_period: time:=20 ns
);
Port ( Rst : In std_logic;
Clk : In std_logic;
Sw : In std_logic_vector (2 downto 0);
Enable : in std_logic;
Led : buffer std_logic_vector (7 downto 0);
Pwm : Out std_logic
);
attribute altera_chip_pin_lc: string;
attribute altera_chip_pin_lc of Clk : signal is "@N2";
attribute altera_chip_pin_lc of Rst : signal is "@G26";
attribute altera_chip_pin_lc of Led : signal is "@AE23, @AF23, @AB21, @AC22, @AD22, @AD23, @AD21, @AC21";
attribute altera_chip_pin_lc of Sw : signal is "@N25,@N26, @P25";
attribute altera_chip_pin_lc of Enable: signal is "@AE14";
end entity Pwm;
Architecture arc_Pwm of Pwm is
constant duty_cycle: integer:=DC/clock_period;
signal Counter : std_logic_vector (16 downto 0);
begin
PwmReg: process (Clk,Rst,Sw)
begin
if (Rst='1') then
Counter <= (others=>'0');
Pwm <='0';
Led <= (others=>'0');
elsif rising_edge(Clk) then
if (Enable='1') then
if (Counter = duty_cycle) then
Counter <= (others => '0');
if (Sw(0) = '1') and (Sw(1) = '0') and (Sw(2) = '0') then
led <= led + 1;
elsif (Sw(0) = '0') and (Sw(1) = '1') and (Sw(2) = '0') then
led <= led - 1;
end if;
else
Counter <= Counter + 1;
end if;
end if;
if (Counter < duty_cycle) then
Pwm <= '1';
else
Pwm <= '0';
end if;
end if;
end process PwmReg;
end architecture arc_Pwm;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
--use std.textio.all;
--use ieee.std_logic_textio.all;
------------------------------------------------------------------------------
entity tb_pwm is
end entity tb_pwm;
------------------------------------------------------------------------------
architecture arc_tb_pwm of tb_pwm is
signal Clk : std_logic := '0'; --
signal Rst : std_logic := '0'; --
signal Sw : std_logic_vector (2 downto 0):= "000"; --
signal Enable : std_logic := '0'; --
signal Pwm : std_logic; --
signal Led : std_logic_vector(7 downto 0); --
begin
test : entity work.pwm
port map (
Clk => Clk,
Rst => Rst,
Enable => Enable,
Sw => Sw,
Pwm => Pwm,
Led => Led );
Clk <= not Clk after 10 ns;
process
begin
wait until rising_edge(Clk);
--wait on switch push;
Enable <= '1';
-- l1 : loop
wait until rising_edge(clk);
--wait for 1 ns;
Sw(0) <= '1';
Sw(1) <= '0';
Sw(2) <= '0';
wait for 0.025us;
wait until rising_edge(clk);
Sw(0) <= '0';
Sw(1) <= '1';
Sw(2) <= '0';
wait for 0.025us;
wait until rising_edge(clk);
Sw(0) <= '0';
Sw(1) <= '0';
Sw(2) <= '1';
wait for 0.025us;
wait until rising_edge(clk);
Enable <= '0';
wait for 0.025us;
wait until rising_edge(clk);
Rst <='0';
wait for 0.025us;
end process;
end architecture arc_tb_pwm;
In the do file I wrote 1us and in the tb iwrote 0.025us in order to see it in the simulaton thanks in advance
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
the duty cycle is 50000, so you need at least this many clock cycles before LED is valid. Your entire simulation runs for 1 us at 100MHz, so you get a grand total of 100 clocks.
Another problem - you dont assert reset so your counter will never count (because it's all 'U' when it does try and count).- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I changed it to dC : time:=100 ns
that means 5 cycles so it should work right? but still no waves- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
your sw settings arnt held for long enough.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
hi,
I changed the sw time to 50 ns even though I dont think its the problme, because the simulation still needed to display the sw waves and I only see clk wave and the others are : pwm - 'u' rst- 'x' others - '0' but know the clock time << sw time , so that solve this issue. I notice that I didnt included the generic map in the tb before so I did it now from a VHDL examples folder and I hope I did it right. but still there no changes in the waves ... so what now?:confused:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
--use std.textio.all;
--use ieee.std_logic_textio.all;
------------------------------------------------------------------------------
entity tb_pwm is
end entity tb_pwm;
------------------------------------------------------------------------------
architecture arc_tb_pwm of tb_pwm is
signal Clk : std_logic := '0'; --
signal Rst : std_logic := '0'; --
signal Sw : std_logic_vector (2 downto 0):= "000"; --
signal Enable : std_logic := '0'; --
signal Pwm : std_logic; --
signal Led : std_logic_vector(7 downto 0); --
begin
test : entity work.pwm
generic map(
DC => 100 ns,
clock_period => 20 ns
)
a port map (
Clk => Clk,
Rst => Rst,
Enable => Enable,
Sw => Sw,
Pwm => Pwm,
Led => Led );
Clk <= not Clk after 10 ns;
process
begin
wait until rising_edge(Clk);
Enable <= '1';
wait until rising_edge(clk);
Sw(0) <= '1';
Sw(1) <= '0';
Sw(2) <= '0';
wait for 100 ns;
wait until rising_edge(clk);
Sw(0) <= '0';
Sw(1) <= '1';
Sw(2) <= '0';
wait for 100 ns;
wait until rising_edge(clk);
Sw(0) <= '0';
Sw(1) <= '0';
Sw(2) <= '1';
wait for 100 ns;
wait until rising_edge(clk);
Enable <= '0';
wait for 100 ns;
wait until rising_edge(clk);
Rst <='0';
wait for 100 ns;
end process;
end architecture arc_tb_pwm;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page