Create two moving objects with VGA controller - vhdl

I am trying to implement a few "ball" bouncing around on a 800x600 screen. I dont completely understand how to make the 2nd ball move on the screen. Right now, it just stays on the screen statically at a certain position.
Here is a shot at what I've done so far.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity pong is
Port ( myclk : in STD_LOGIC;
rgb : out STD_LOGIC_VECTOR (2 downto 0);
hs : out STD_LOGIC;
vs : out STD_LOGIC);
end pong;
architecture Behavioral of pong is
signal clk: STD_LOGIC;
signal horz_scan: STD_LOGIC_VECTOR (9 downto 0);
signal vert_scan: STD_LOGIC_VECTOR (9 downto 0);
signal vinc_flag: STD_LOGIC;
signal dx: STD_LOGIC;
signal dy: STD_LOGIC;
signal refresh_counter: STD_LOGIC;
signal posx: integer := 300;
signal posy: integer := 300;
signal color: STD_LOGIC_VECTOR (2 downto 0) := "111";
signal vinc_flag2: STD_LOGIC;
signal dx2: STD_LOGIC;
signal dy2: STD_LOGIC;
signal posx2: integer := 300;
signal posy2: integer := 300;
signal color2: STD_LOGIC_VECTOR (2 downto 0) := "001";
signal refresh_counter2: STD_LOGIC;
signal horz_scan2: STD_LOGIC_VECTOR (9 downto 0);
signal vert_scan2: STD_LOGIC_VECTOR (9 downto 0);
signal clk2: STD_LOGIC;
begin
-- Clock divide by 1/2
process(myclk)
begin
if myclk = '1' and myclk'Event then
clk <= not clk;
end if;
end process;
-- horizonal clock
process(clk)
begin
if clk = '1' and clk'Event then
if horz_scan = "1100100000" then
horz_scan <= "0000000000";
else
horz_scan <= horz_scan + 1;
end if;
end if;
end process;
-- vertial clock (increments when the horizontal clock is on the front porch
process(vinc_flag)
begin
if vinc_flag = '1' and vinc_flag'Event then
if vert_scan = "1000001001" then
vert_scan <= "0000000000";
refresh_counter <= refresh_counter xor '1';
else
vert_scan <= vert_scan + 1;
end if;
end if;
end process;
process(vinc_flag2)
begin
if vinc_flag2 = '1' and vinc_flag2'Event then
if vert_scan2 = "1000001001" then
vert_scan2 <= "0000000000";
refresh_counter2 <= refresh_counter2 xor '1';
else
vert_scan2 <= vert_scan2 + 1;
end if;
end if;
end process;
process(refresh_counter)
begin
if refresh_counter = '1' and refresh_counter'Event then
if dx = '0' then
posx <= posx + 1;
else
posx <= posx -1;
end if;
if dy = '0' then
posy <= posy + 1;
else
posy <= posy -1;
end if;
color <= "100";
end if;
end process;
process(refresh_counter2)
begin
if refresh_counter2 = '1' and refresh_counter2'Event then
if dx2 = '0' then
posx2 <= posx2 + 1;
else
posx2 <= posx2 -1;
end if;
if dy2 = '0' then
posy2 <= posy2 + 1;
else
posy2 <= posy2 -1;
end if;
color2 <= "001";
end if;
end process;
process(posx)
begin
if posx = 144 then
dx <= '0';
elsif posx = 734 then
dx <= '1';
end if;
end process;
process(posy)
begin
if posy = 35 then
dy <= '0';
elsif posy = 465 then
dy <= '1';
end if;
end process;
process(posx2)
begin
if posx = 144 then
dx <= '0';
elsif posx = 734 then
dx <= '1';
end if;
end process;
process(posy2)
begin
if posy = 35 then
dy <= '0';
elsif posy = 465 then
dy <= '1';
end if;
end process;
-- horizontal sync for 96 horizontal clocks (96 pixels)
hs <= '1' when horz_scan < 96 else '0';
-- vertial sync for 2 scan lines
vs <= '1' when vert_scan(9 downto 1) = "000000000" else '0';
rgb <= color when (vert_scan >= posy and vert_scan < (posy+50) and horz_scan >= posx and horz_scan < posx+50) or (vert_scan >= posy2 and vert_scan < (posy2+50) and horz_scan >= posx2 and horz_scan < (posx2+50)) else "000";
vinc_flag <= '1' when horz_scan = "1100011000" else '0';
end Behavioral;

There seems to be a copy and paste error in your code. The last two processes are sensitive to posx2 and posy2 respectively, but you seem to be changing the state of the first ball (dx and dy). Shouldn't you be changing dx2 and dy2 instead?
Also, here are two suggestions to make your code more readable:
Instead of declaring your counters as std_logic_vectors and comparing them against bit-string literals (e.g., if vert_scan2 = "1000001001" then ...), why not declare the counters as integers? That would contribute to making you code more readable.
Don't use "magic numbers" or hardcoded literals spread throughout your code (e.g., in the expression if posx = 144 then ..., 144 is a magic number). Instead, create a constant with a meaningful name (constant BALL_X_POS_MIN: integer := 144;) and use it in your expressions (if posx = BALL_X_POS_MIN then ...).

Related

Counter 0-30 But Clock connected - VHDL code

I made a counter 1-30. but I got this
My schematic here. I remove counter0-3
and It's here I found the problem here. It's the clock connected with a new loop
So I want to increase the size of the clock. Like this
I'm a rookie here, I don't know how to do that. Please give me an idea, thanks
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity counter0_9x is
port(
clk : in std_logic;
clk_B : in std_logic;
reset : in std_logic;
counter : out std_logic_vector(3 downto 0);
clk_o : out std_logic
);
end counter0_9x;
architecture Behavioral of counter0_9x is
signal counter_up : std_logic_vector(3 downto 0);
begin
process(clk,reset)
variable num : integer := 0;
begin
if(reset='1')then
counter_up <= "0000";
elsif(clk'event and clk = '1')then
if clk_B = '0' then
if num <= 2 then
if counter_up = "1001" then
counter_up <= "0000";
num := num + 1;
clk_o <= '1';
else
counter_up <= counter_up + '1';
clk_o <= '0';
end if;
else
if counter_up = "0000" then
counter_up <= "0000";
num := 0;
clk_o <= '1';
else
counter_up <= counter_up + '1';
clk_o <= '0';
end if;
end if;
end if;
end if;
end process;
counter <= counter_up;
end Behavioral;
Update!!!
I have tried combinational but I still can't shrink "clk_o"
architecture Behavioral of counter0_9x is
signal counter_up : std_logic_vector(3 downto 0);
begin
process(clk,reset)
variable num : integer range 0 to 2 := 0;
begin
if(reset='1')then
counter_up <= "0000";
elsif(clk'event and clk = '1')then
if clk_B = '0' then
if num <= 1 then
if counter_up = "1001" then
counter_up <= "0000";
num := num + 1;
else
counter_up <= counter_up + '1';
end if;
else
if counter_up = "0000" then
counter_up <= "0000";
num := 0;
else
counter_up <= counter_up + '1';
end if;
end if;
end if;
end if;
end process;
counter <= counter_up;
with counter_up select
clk_o <= '1' when "0000",
'0' when others;
end Behavioral;
At firth sight this is caused by assigning the signal ("clk_o") insight a sequential process (process that is (edge) triggered by your clock).
This creates a flipflop that stores the signal value until the next rising edge of the clock.
You want to achive combinational logic. You have to create a separate process for the assignment of signal "clk_o" without any clock. (Don't forget to add the necessary signals to the sensitivity list.)
It might also be helpful to visualize the synthesis of your vhdl code using pen and paper to better predict the extracted logic.

How can i reduce number of ALMs in my VHDL design?

I'm trying to implement an alarm module for the digital clock in VHDL. I have written architecture for it, but when I run Compilation I get too many Adaptive Logic Modules (around 2000), which I think is too much. I will post my code below.
I think division and modulus operation could be causing it, in this line of code.
alarm_hour1 <= std_logic_vector(to_unsigned(savedHours/10,alarm_hour1'length));
alarm_hour0 <= std_logic_vector(to_unsigned(savedHours mod 10,alarm_hour0'length));
alarm_minute1 <= std_logic_vector(to_unsigned(savedMinutes/10,alarm_minute1'length));
alarm_minute0 <= std_logic_vector(to_unsigned(savedMinutes mod 10,alarm_minute0'length));
Still, I'm not sure how can I work around this.
Also, I would be very grateful if You give more comments on my design, and point out some mistakes, and ways how I can improve my design. I'm fairly new to VHDL so any advice is appreciated.
Thanks a lot.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity alarm is
port(
--INPUTS
reset : in std_logic;
clock : in std_logic;
alarm_enable : in std_logic;
alarm_set : in std_logic;
alarm_increment : in std_logic;
alarm_decrement : in std_logic;
currentTime_hour1 : in std_logic_vector(3 downto 0);
currentTime_hour0 : in std_logic_vector(3 downto 0);
currentTime_minute1 : in std_logic_vector(3 downto 0);
currentTime_minute0 : in std_logic_vector(3 downto 0);
--OUTPUTS
alarm_buzzer : out std_logic;
alarm_hour1 : buffer std_logic_vector(3 downto 0) := "0000";
alarm_hour0 : buffer std_logic_vector(3 downto 0) := "0000";
alarm_minute1 : buffer std_logic_vector(3 downto 0) := "0000";
alarm_minute0 : buffer std_logic_vector(3 downto 0) := "0000"
);
end alarm;
architecture alarmBehaviour of alarm is
--ALARM TIME
signal savedHours : integer := 0;
signal savedMinutes : integer := 0;
signal incrementDecrementbuttonDetect : std_logic;
signal set_lastButtonState : std_logic := '0';
signal setButtonDetect : std_logic := '0';
--STATE MACHINE
type state_type is (idle, setHour, setMinute);
signal state_reg, state_next : state_type;
begin
incrementDecrementbuttonDetect <= alarm_increment or alarm_decrement;
--STATE REGISTER
process(clock, reset)
begin
if (reset = '1') then
state_reg <= idle;
elsif rising_edge(clock) then
state_reg <= state_next;
end if;
end process;
--SET BUTTON PRESSED
process(clock)
begin
if(rising_edge(clock)) then
if(alarm_set = '1' and set_lastButtonState = '0') then
setButtonDetect <= '1';
else
setButtonDetect <= '0';
end if;
set_lastButtonState <= alarm_set;
end if;
end process;
--NEXT STATE
process(state_reg, setButtonDetect)
begin
case state_reg is
when idle =>
if setButtonDetect = '1' then
state_next <= setHour;
else
state_next <= idle;
end if;
when setHour =>
if setButtonDetect = '1' then
state_next <= setMinute;
else
state_next <= setHour;
end if;
when setMinute =>
if setButtonDetect = '1' then
state_next <= idle;
else
state_next <= setMinute;
end if;
end case;
end process;
process (incrementDecrementbuttonDetect, state_reg)
begin
if rising_edge(incrementDecrementbuttonDetect) then
case state_reg is
when idle =>
when setHour =>
if alarm_increment = '1' then
if savedHours = 23 then
savedHours <= 0;
else
savedHours <= savedHours + 1;
end if;
else null;
end if;
if alarm_decrement = '1' then
if savedHours = 0 then
savedHours <= 23;
else
savedHours <= savedHours - 1;
end if;
else null;
end if;
when setMinute =>
if alarm_increment = '1' then
if savedMinutes = 59 then
savedMinutes <= 0;
else
savedMinutes <= savedMinutes + 1;
end if;
else null;
end if;
if alarm_decrement = '1' then
if savedMinutes = 0 then
savedMinutes <= 59;
else
savedMinutes <= savedMinutes - 1;
end if;
else null;
end if;
end case;
end if;
end process;
alarm_hour1 <= std_logic_vector(to_unsigned(savedHours/10,alarm_hour1'length));
alarm_hour0 <= std_logic_vector(to_unsigned(savedHours mod 10,alarm_hour0'length));
alarm_minute1 <= std_logic_vector(to_unsigned(savedMinutes/10,alarm_minute1'length));
alarm_minute0 <= std_logic_vector(to_unsigned(savedMinutes mod 10,alarm_minute0'length));
--ALARM BUZZER CONDITION
process (currentTime_hour1, currentTime_hour0, currentTime_minute1, currentTime_minute0,
alarm_enable, alarm_hour1, alarm_hour0, alarm_minute1, alarm_minute0)
begin
if((alarm_hour1 = currentTime_hour1) and (alarm_hour0 = currentTime_hour0)
and (alarm_minute1 = currentTime_minute1) and (alarm_minute0 = currentTime_minute0) and alarm_enable = '1') then
alarm_buzzer <= '1';
else
alarm_buzzer <= '0';
end if;
end process;
end alarmBehaviour;
Consider keeping the alarm time in Binary-Coded Decimal (BCD) format instead of binary format, whereby you can compare it directly with the current time, that is provided in BCD format.
This is a good example of how using the appropriate internal data format can reduce the computational problem significantly, since you can simply eliminate the costly division and modulo operations by keeping just one data format (BCD) instead of mixing BCD and binary data formats.
The range of signals savedHours and savedMinutes is not specified, so Quartus assumes they are 32 bits wide. Inference of a divider with one 32-bit operand results into a large tree of conditional subtractions.
Updating your code to something like
--ALARM TIME
signal savedHours : natural range 0 to 23 := 0;
signal savedMinutes : natural range 0 to 59 := 0;
will very likely result into less ALM usage.
Also, please note that rising_edge should be used for clock signals only (at VHDL starter level). Instead of connecting logic to the clock input of a register, what you probably want is some button debounce logic.

Spikes or glitches in Modelsim

I've been learning VHDL for a while and I'm making a project right now. I made a NCO (Numerically controlled Oscillator) and a cordic algorithm to produce sine and cosine with a certain frequency.
I don't know why I get spikes on my waves in Modelsim. I guess they are caused by the case statement when it changes the quadrant for the cordic algorithm to work with angles between -180 and +180.
I've read that it could be a "normal" behavior of Modelsim because of the iterations of the simulator (VHDL delta cycles). But I don't know how and if I should fix them.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY phase_accumulator_module IS
GENERIC (
LGTBL: INTEGER := 16; --lunghezza table log base 2
W: INTEGER := 32;
OW: INTEGER := 16
);
PORT (
clk: IN STD_LOGIC;
reset: IN STD_LOGIC;
i_dphase: IN STD_LOGIC_VECTOR(W-1 DOWNTO 0);
o_val: BUFFER STD_LOGIC_VECTOR(W-1 DOWNTO 0);
o_val_test:BUFFER STD_LOGIC_VECTOR(OW-1 DOWNTO 0);
o_val_laser: BUFFER STD_LOGIC_VECTOR(W-1 DOWNTO 0);
quadrant: BUFFER STD_LOGIC_VECTOR(1 DOWNTO 0)
);
END phase_accumulator_module;
ARCHITECTURE behave OF phase_accumulator_module IS
SIGNAL r_step,r_step_laser,r_step_test: STD_LOGIC_VECTOR(W-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL r_phase,r_phase_laser,r_phase_test: STD_LOGIC_VECTOR(W-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL r_phase_pipe,r_phase_laser_pipe: STD_LOGIC_VECTOR(W-1 DOWNTO 0) := (OTHERS => '0');
CONSTANT P: INTEGER := LGTBL;
BEGIN
R_Step_pro: PROCESS(clk,reset)
BEGIN
IF(reset='1') THEN
r_step <= (OTHERS=>'0');
r_step_test <= (OTHERS=>'0');
r_step_laser <= (OTHERS=>'0');
ELSE IF(rising_edge(clk)) THEN
r_step <= i_dphase; -- 2^W*f/fs
r_step_test <= i_dphase; --test signal
r_step_laser <= STD_LOGIC_VECTOR(SHIFT_RIGHT(UNSIGNED(i_dphase),1));
END IF;
END IF;
END PROCESS R_Step_pro;
R_phase_pro: PROCESS(clk,reset)
BEGIN
IF(reset='1') THEN
r_phase <= (OTHERS=>'0');
r_phase_test <= (OTHERS=>'0');
r_phase_laser <= (OTHERS=>'0');
o_val <= (OTHERS=>'0');
o_val_test <= (OTHERS=>'0');
o_val_laser <= (OTHERS=>'0');
ELSE IF(rising_edge(clk)) THEN
r_phase <= STD_LOGIC_VECTOR(UNSIGNED(r_phase) + UNSIGNED(r_step));
r_phase_test <= STD_LOGIC_VECTOR(UNSIGNED(r_phase_test) + UNSIGNED(r_step_test)); --test signal
r_phase_laser <= STD_LOGIC_VECTOR(UNSIGNED(r_phase_laser) + UNSIGNED(r_step_laser));
quadrant <= r_phase(W-1 DOWNTO w-2);
CASE quadrant IS
WHEN "00" | "11" =>
r_phase_pipe <= r_phase;
r_phase_laser_pipe <= r_phase_laser;
WHEN "01" =>
r_phase_pipe <= "00" & r_phase(W-3 DOWNTO 0);
r_phase_laser_pipe <= "00" & r_phase_laser(W-3 DOWNTO 0);
WHEN "10" =>
r_phase_pipe <= "11" & r_phase(W-3 DOWNTO 0);
r_phase_laser_pipe <= "11" & r_phase_laser(W-3 DOWNTO 0);
WHEN OTHERS =>
null;
END CASE;
o_val_test <= r_phase_test(W-1 DOWNTO W-P);
o_val <= r_phase_pipe;
o_val_laser <= r_phase_laser_pipe;
END IF;
END IF;
END PROCESS R_phase_pro;
END behave;
This is the cordic algotithm vhdl file:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY signal_gen_cordic_module IS
GENERIC (
bits: INTEGER := 16;
bits_out_c: INTEGER := 32;
iter : INTEGER := 32
);
PORT (
clk: IN STD_LOGIC;
reset: IN STD_LOGIC;
locked: IN STD_LOGIC;
z0: IN STD_LOGIC_VECTOR (bits_out_c-1 DOWNTO 0);
quadrant: IN STD_LOGIC_VECTOR(1 DOWNTO 0);
sine,cosine: BUFFER STD_LOGIC_VECTOR(bits-1 DOWNTO 0)
);
END signal_gen_cordic_module;
ARCHITECTURE behave OF signal_gen_cordic_module IS
TYPE temp IS ARRAY (0 TO iter-1) OF STD_LOGIC_VECTOR(bits_out_c-1 DOWNTO 0);
SIGNAL x_temp,y_temp,z_temp: temp;
CONSTANT x0: SIGNED(bits_out_c-1 DOWNTO 0) := "00000000000000000010111100011010"; --0.6072*2^16
CONSTANT y0: SIGNED(bits_out_c-1 DOWNTO 0) := "00000000000000000000000000000000";
SIGNAL x00,y00: SIGNED(bits_out_c-1 DOWNTO 0);
TYPE atand IS ARRAY (0 TO iter-1) OF STD_LOGIC_VECTOR(bits_out_c-1 DOWNTO 0);
CONSTANT arctan: atand :=
(
x"20000000",
x"12E4051E",
x"09FB385B",
x"051111D4",
x"028B0D43",
x"0145D7E1",
x"00A2F61E",
x"00517C55",
x"0028BE53",
x"00145F2F",
x"000A2F98",
x"000517CC",
x"00028BE6",
x"000145F3",
x"0000A2FA",
x"0000517D",
x"000028BE",
x"0000145F",
x"00000A30",
x"00000518",
x"0000028C",
x"00000146",
x"000000A3",
x"00000051",
x"00000029",
x"00000014",
x"0000000A",
x"00000005",
x"00000003",
x"00000001",
x"00000001",
x"00000000"
);
BEGIN
PROCESS(clk,reset)
BEGIN
IF(reset='1') THEN
cosine <= (OTHERS=>'0');
sine <= (OTHERS=>'0');
FOR i IN iter-1 DOWNTO 0 LOOP
x_temp(i) <= (OTHERS=>'0');
y_temp(i) <= (OTHERS=>'0');
z_temp(i) <= (OTHERS=>'0');
END LOOP;
ELSE IF(rising_edge(clk)) THEN
IF(locked='1') THEN
IF(quadrant="00" OR quadrant="11") THEN
x00 <= x0;
y00 <= y0;
ELSE IF(quadrant="01") THEN
x00 <= -y0;
y00 <= x0;
ELSE
x00 <= y0;
y00 <= -x0;
END IF;
END IF;
x_temp(0) <= STD_LOGIC_VECTOR(x00);
y_temp(0) <= STD_LOGIC_VECTOR(y00);
z_temp(0) <= z0;
FOR i IN 0 TO iter-2 LOOP
IF(z_temp(i)(z0'HIGH)='1') THEN
x_temp(i+1) <= STD_LOGIC_VECTOR(SIGNED(x_temp(i)) + SHIFT_RIGHT(SIGNED(y_temp(i)),i));
y_temp(i+1) <= STD_LOGIC_VECTOR(SIGNED(y_temp(i)) - SHIFT_RIGHT(SIGNED(x_temp(i)),i));
z_temp(i+1) <= STD_LOGIC_VECTOR(SIGNED(z_temp(i)) + SIGNED(arctan(i)));
ELSE
x_temp(i+1) <= STD_LOGIC_VECTOR(SIGNED(x_temp(i)) - SHIFT_RIGHT(SIGNED(y_temp(i)),i));
y_temp(i+1) <= STD_LOGIC_VECTOR(SIGNED(y_temp(i)) + SHIFT_RIGHT(SIGNED(x_temp(i)),i));
z_temp(i+1) <= STD_LOGIC_VECTOR(SIGNED(z_temp(i)) - SIGNED(arctan(i)));
END IF;
END LOOP;
cosine <= STD_LOGIC_VECTOR(RESIZE(SIGNED(x_temp(iter-1)),bits));
sine <= STD_LOGIC_VECTOR(RESIZE(SIGNED(y_temp(iter-1)),bits));
END IF;
END IF;
END IF;
END PROCESS;
END behave;
My modelsim version is 10.5b. Thank you for any help! :)

VHDL code not working on board but works on simulation

i'm working on a project using vhdl to configure a fpga board spartan 3E. what i have to do is a genius puzzle, in my main code there is a state machine to control the logic.
everything works well when i simulate the code using xilinx simulator but when i run the .bit file to the FPGA board what happens is that the first led of the sequence turns on and then turns off, this should happen but then when i click the right button it just stop working and the next sequence is never shown.
of course there is a issue of deboucing the buttons, and that's the reason i'm using a counter to prevent the repic to bug the system.
i'm working hard on this code to function but this issue doesn't go away, maybe i'm doing something wrong i don't know or i'm not doing something i should.
here is my main code, which is the state machine and a clock proccess with the counter.
Flag_conte = starts ou blocks the counter
Flag_estou_contando = 1=counting, 0= not counting, 3= just finished count.
BCD = board buttons IN
LEDs = corresponds to 4 leds that will show the sequence in the game
entity Algoritmo is
port(
clk: in std_logic;
BCD: in std_logic_vector (3 downto 0);
botaoStart: in std_logic;
botaoReset: in std_logic;
seven_seg: out std_logic_vector(6 downto 0);
anode: out std_logic_vector(3 downto 0);
LEDS: out std_logic_vector(3 downto 0)
);
END Algoritmo;
architecture Behavioral of Algoritmo is
subtype state_type is integer range 5 downto 0;
signal state, nextstate: state_type:=0;
signal Inicio, nclk: std_logic:= '0';
--variable posicaoAtual: integer :=0;
type mem1 is array (0 to 13) of std_logic_vector (3 downto 0);
constant vetorSequencia: mem1 := ( "0001", "0010", "0100", "1000", "0001", "0010", "0100", "1000", "0001", "0010", "0100", "1000", "0001", "0010");
constant generic1hz: integer:= 12_500_000;
signal t3count:integer:=0;
signal posA, posB, signalScore, Flag_conte,
Flag_estou_contando:integer:=0;
signal valor: integer :=12_500_000;
Begin
-------------
process (state,BCD,botaoStart,Flag_estou_contando)
variable Pos: integer :=0;
variable score: integer:=0;
variable posicaoAtual: integer:=0;
variable tentativa: std_logic_vector (3 downto 0);
begin
case state is
when 0 => if (botaoStart = '0')
then nextstate <= 0;-- estado idle, esperando entrada do tclado,led1=1;
else nextstate <= 1;
end if;
when 1 =>-- if(Flag_estou_contando =0)then
if(nextstate=2)then
Flag_conte <=0;
nextstate <= 2;
else if (nextstate/=2)then
if (posicaoAtual < score)then
if(Flag_estou_contando=0)then
LEDS <= vetorSequencia(posicaoAtual);
posA <= posicaoAtual;
Flag_conte<=1;
valor<=10_000_000;
else if(Flag_estou_contando=1)then
LEDS <=vetorSequencia(posicaoAtual);
else if (Flag_estou_contando=3)then
--posicaoAtual:=0;
posicaoAtual := posicaoAtual + 1;
posA <= posicaoAtual;
nextstate <=1;
Flag_conte<=0;
end if;end if;end if;
else if(posicaoAtual = score)then
if(Flag_estou_contando=0)then
Flag_conte<=1;
valor<=10_000_000;
-- posicaoAtual :=0;
posA <= posicaoAtual;
else if(Flag_estou_contando=1)then
LEDS <=vetorSequencia(posicaoAtual);
nextstate<=1;
else if(Flag_estou_contando=3)then
posicaoAtual:=0;
posA <= posicaoAtual;
Flag_conte<=0;
nextstate <= 2;
end if;end if;end if;
end if;end if;
Flag_conte <=1;
end if;end if;
when 2 => --if(Flag_estou_contando=0)then
if (BCD = "0000")then
if(Flag_estou_contando=0)then
LEDS <= "0000"; --nextstate <= 2;
else if (Flag_estou_contando=1)then
nextstate<=2;
else if (Flag_estou_contando=3)then
Flag_conte <= 0;
nextstate<=3;
end if;end if;end if;
else if(BCD /= "0000")then
if(Flag_estou_contando=0)then
Flag_conte<=1;
valor<=200_000_000;
tentativa := BCD;
LEDS <= tentativa;
else if(Flag_estou_contando=3)then
nextstate <= 3;
else if(Flag_estou_contando=1)then
LEDS <= tentativa;
nextstate <=2;
end if;end if;end if;
end if;end if;
when 3 => if (vetorSequencia(Pos) = tentativa)then
if (Pos < score)then
nextstate <= 2;
Pos := Pos + 1;
posB <= Pos;
else if(Pos = score)then
score := score + 1;
signalScore <= score;
nextstate <= 1;
Pos := 0;
if (score = 15)-- if score =15 finish game
then nextstate <= 5;
end if;--end if
end if;end if;
else -- se estiver errado, perde o jogo
nextstate <= 4; -- goes to game over
end if;
when 4 => if (botaoReset = '1') -- game over
then nextstate <= 4;-- "U LOST nOOB"
elsif (botaoReset = '0')
then nextstate <= 0; --
end if;
when 5 => if (botaoReset = '1') -- jogo ganho
then nextstate <= 5; -- "GG"
elsif (botaoReset = '0')
then nextstate <= 0;
end if;
end case;
end process;
process (clk, Flag_conte)
variable sum, count :integer:=0;
begin
if rising_edge(clk) then
if(Flag_estou_contando = 0) then
if (Flag_conte = 1) then
count :=0;
Flag_estou_contando <=1;
end if;
end if;
if(Flag_estou_contando=3) then
if(Flag_conte =0)then
Flag_estou_contando <= 0;
else
Flag_estou_contando <=3;
end if;
end if;
if (Flag_estou_contando =1)then
if(count < valor)then
count := count + 1;
else
count:=0;
Flag_estou_contando <=3;
end if;
end if;
sum := sum +1;
if(sum = generic1hz)then -- 1hz generate
state <= nextstate;
nclk <= not nclk;
sum := 0;--restart count for 1hz generate
end if;
end if;
end process;
end Behavioral;
if i wasnt clear, please let me know i will try to explain better, if anyone could help i would be very greatful, thank you for your time.
You should try post place & route simulation to verify whats happen:
http://www.xilinx.com/support/documentation/sw_manuals/xilinx11/pp_p_process_simulate_post_place.htm
With some family device you can use chipscope technology to debug:
https://www.xilinx.com/support/documentation/sw_manuals/xilinx10/isehelp/ise_c_process_analyze_design_using_chipscope.htm
Sorry for my English.
Regards.

VHDL Code for Binary Division bug

I've written code for a binary divider that takes in an 8 bit dividend, 3 bit divisor, and gives a 5 bit quotient (3 bit remainder). I've literally spent hours trying to fix a bug that gives incorrect results but I haven't been able to identify it. Any help would be GREATLY appreciated! I basically get wrong answers for my inputs but I can't figure out why. There is a bus that takes in values and on the first clock cycle where st is 1, the dividend register is loaded. On the second clock cycle after, the divisor register is loaded and the calculation is made for the next three clock cycles.
The V signal is the output to signify that an overflow has occured (the result can't be fit into the five bits of the quotient), my st is the start signal to start the process, sh is the shift signal for the shift register, su is the subtract signal for the subtractor.
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity Divider is
Port (bus_in: in std_logic_vector(8 downto 0);
St, Clk, reset: in std_logic;
Quotient: out std_logic_vector(4 downto 0);
Remainder: out std_logic_vector(2 downto 0);
v: out std_logic);
end Divider;
architecture Behavioral of Divider is
signal State, NextState: integer range 0 to 5;
signal C, Ld1, Ld2, Su, Sh: std_logic;
signal Divisor: std_logic_vector(2 downto 0);
signal Subout: std_logic_vector(3 downto 0);
signal Dividend: std_logic_vector(8 downto 0);
begin
Subout <= Dividend(8 downto 5) - ('0' & divisor);
C <= not Subout (3);
Remainder <= Dividend(7 downto 5);
Quotient <= Dividend(4 downto 0);
State_Graph: process (State, St, C)
begin
Ld1 <= '0';
Ld2<='0';
v <= '0';
Sh <= '0';
Su <= '0';
case State is
when 0 =>
if (St = '1') then
Ld1 <= '1';
NextState <= 1;
else
NextState <= 0;
end if;
when 1 =>
if (St = '1') then
Ld2 <= '1';
NextState <= 2;
else
Ld2<='1';
NextState <= 2;
end if;
when 2 =>
if (C = '1') then
v <= '1';
NextState <= 0;
else
Sh <= '1';
NextState <= 3;
end if;
when 3 | 4 =>
if (C = '1') then
Su <= '1';
NextState <= State;
else
Sh <= '1';
NextState <= State + 1;
end if;
when 5 =>
if (C = '1') then
Su <= '1';
end if;
NextState <= 0;
end case;
end process State_Graph;
Update: process (Clk)
begin
if Clk'event and Clk = '1' then
State <= NextState;
--if Load = '1' then
-- Dividend <= '0' & bus_in;
--end if;
if Ld1 = '1' then
Dividend <= '0'&Bus_in(7 downto 0);
end if;
if Ld2 = '1' then
Divisor <= Bus_in(2 downto 0);
end if;
if Su = '1' then
Dividend(8 downto 5) <= Subout;
Dividend(0) <= '1';
end if;
if Sh = '1' then --94
Dividend <= Dividend(7 downto 0) & '0';
end if;
end if;
end process update;
end Behavioral;
Here's my input and outputs:
[Signals]: http://imgur.com/fqfiYJZ 1
The picture shows that my registers for the divisor and dividend is loading correctly. So I think the issue is with the actual division code. The state machine also seems to be working correctly.
Don't write this yourself. You are re-inventing the wheel.
Either write q <= a / b;
or use an IP core from your FPGA vendor.

Resources