I am literally writing this in desperation. i've tried some many times to make it work and it just doesn't.
im using Altera DE2 board - Cyclone II EP2C35F672C6 & been trying to display simple image on 640x480 vga screen.
im using a vga controller design i made for a different board- Altera DE1 which worked really good.
the difference on this DE2 board is a different DAC component which has 10bit rgb data instead of 4bit like in the DE1 board, and it has extra needed ouputs - VGA_SYNC, VGA_BLANK, VGA_CLK.
So i made the needed changes & found an example where it says to set VGA_BLANK to '1' constant and VGA_SYNC to '0'. VGA_CLK is connected to the 25.175 Mhz pixel clk which is the pll clk output.
i've tried so many variations & tried to use another example where they set vga_blank to '1' when in visable aread & '0' when not and it still didnt work. i just get a black screen saying no video input when i run the design.
below is the implementation of my timing generator, data_generator & vga_top_level
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.vga_consts.all;
entity vga_toplevel is
port
(
-- in --
clk, rst : in std_logic;
-- out --
vga_clk, vga_blank, vga_sync : out std_logic;
r_data, g_data, b_data : out std_logic_vector(9 downto 0);
h_sync, v_sync : out std_logic
);
end entity;
architecture structural of vga_toplevel is
component pll
port
(
areset : IN STD_LOGIC := '0';
inclk0 : IN STD_LOGIC := '0';
c0 : OUT STD_LOGIC ;
locked : OUT STD_LOGIC
);
end component;
component timing_generator
port
(
clk, rst : in std_logic;
h_cnt : out integer range 0 to h_frame-1;
v_cnt : out integer range 0 to v_frame-1;
vga_blank, vga_sync : out std_logic;
h_sync, v_sync : out std_logic
);
end component;
component data_generator
generic
(
vis_x : integer := visable_x;
vis_y : integer := visable_y
);
port
(
clk, rst : in std_logic;
h_cnt : in integer range 0 to h_frame-1;
v_cnt : in integer range 0 to v_frame-1;
-- RGB values
r_data, g_data, b_data : out std_logic_vector(9 downto 0)
);
end component;
signal h_cnt, v_cnt : integer range 0 to h_frame-1;
signal pll_clk, rst_out, locked : std_logic;
-------------------------------------------------------------------
begin
rst_out <= not locked; -- uncomment for PLL use
vga_clk <= pll_clk;
-- rst_out <= rst; -- comment for PLL use
-- pll_clk <= clk; -- comment for PLL use
PLL1: pll
port map
(
inclk0 => clk,
areset => rst,
c0 => pll_clk,
locked => locked
);
T_GEN: timing_generator
port map
(
-- in --
clk => pll_clk,
rst => rst_out,
-- out --
vga_blank => vga_blank,
vga_sync => vga_sync,
v_cnt => v_cnt,
h_cnt => h_cnt,
v_sync => v_sync,
h_sync => h_sync
);
D_GEN: data_generator
port map
(
-- in --
clk => pll_clk,
rst => rst_out,
v_cnt => v_cnt,
h_cnt => h_cnt,
r_data => r_data,
g_data => g_data,
b_data => b_data
);
end architecture;
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.vga_consts.all;
entity timing_generator is
port
(
clk, rst : in std_logic;
h_cnt : out integer range 0 to h_frame-1;
v_cnt : out integer range 0 to v_frame-1;
vga_blank : out std_logic;
vga_sync : out std_logic;
h_sync, v_sync : out std_logic
);
end entity;
architecture behave of timing_generator is
signal h_cnt_inner : integer range 0 to h_frame-1;
signal v_cnt_inner : integer range 0 to v_frame-1;
begin
vga_blank <= '1';
vga_sync <= '0';
h_cnt <= h_cnt_inner;
v_cnt <= v_cnt_inner;
-- counter for pixels --
process (clk, rst)
begin
if rst = '1' then
h_cnt_inner <= 0;
elsif rising_edge(clk) then
if h_cnt_inner = h_frame-1 then
h_cnt_inner <= 0;
else
h_cnt_inner <= h_cnt_inner + 1;
end if;
end if;
end process;
-- counter for lines --
process (clk, rst)
begin
if rst = '1' then
v_cnt_inner <= 0;
elsif rising_edge(clk) then
if v_cnt_inner = v_frame-1 then
v_cnt_inner <= 0;
elsif h_cnt_inner = 654 then
v_cnt_inner <= v_cnt_inner + 1;
end if;
end if;
end process;
-- h_sync generator --
process (clk, rst)
begin
if rst = '1' then
h_sync <= '1';
elsif rising_edge(clk) then
if h_cnt_inner = h_sync_d(0)-1 then
h_sync <= '0';
elsif h_cnt_inner = h_sync_d(1) then
h_sync <= '1';
end if;
end if;
end process;
-- v_sync generator --
process(clk, rst)
begin
if rst = '1' then
v_sync <= '1';
elsif rising_edge(clk) then
if v_cnt_inner = v_sync_d(0) then
v_sync <= '0';
elsif v_cnt_inner = v_sync_d(1) + 1 then
v_sync <= '1';
end if;
end if;
end process;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.vga_consts.all;
entity data_generator is
generic (
vis_x : integer := visable_x;
vis_y : integer := visable_y
);
port
(
clk, rst : in std_logic;
h_cnt : in integer range 0 to h_frame-1;
v_cnt : in integer range 0 to v_frame-1;
-- RGB values for each pixel
r_data, g_data, b_data : out std_logic_vector(9 downto 0)
);
end entity;
architecture behave of data_generator is
begin
-- process to handle only 1 color - blue screen
process(clk, rst)
begin
if rst = '1' then
r_data <= (others => '0');
g_data <= (others => '0');
b_data <= (others => '0');
elsif rising_edge(clk) then
if (h_cnt >= h_vis_d(0)) and (h_cnt < h_vis_d(1)) and (v_cnt >= v_vis_d(0)) and (v_cnt < v_vis_d(1)) then
-- if in visiable area
r_data <= (others => '1');
g_data <= (others => '1');
b_data <= (others => '1');
else
r_data <= (others => '0');
g_data <= (others => '0');
b_data <= (others => '0');
end if;
end if;
end process;
end architecture;
Related
I am confused on to why my VHDL design is not working. I am to create a top.vhd file that will program an FPGA board to display addresses 0 through 15 and the corresponding values to each address. When I simulate my design, all the clocks and resets work. The problem I am having is my FSM processes and Address process. I know there is a lot going on here, so if you need clarification I can answer your questions.
library IEEE;
use IEEE.std_logic_1164.ALL;
use IEEE.numeric_std.all;
entity top is
port(Clock : in std_logic;
Reset : in std_logic;
SW : in std_logic_vector (1 downto 0);
HEX2, HEX4: out std_logic_vector ( 6 downto 0);
KEY0: in std_logic);
end entity;
architecture top_arch of top is
component char_decoder is
port(BIN_IN : in std_logic_vector (3 downto 0);
HEX_OUT : out std_logic_vector (6 downto 0));
end component;
component rom_16x4_sync is
port (clock: in std_logic;
address: in std_logic_vector (3 downto 0);
rom_en: in std_logic;
data_out: out std_logic_vector(3 downto 0));
end component;
type state_type is (start, read_rom, clear_addr, done);
signal current_state, next_state : state_type;
signal Rom_en, addr_count_clr, addr_count_en : std_logic;
signal address_counter : integer range 0 to 15;
signal address_uns : unsigned (3 downto 0);
signal clock_slow : std_logic;
signal rom_out : std_logic_vector (3 downto 0);
begin
char : char_decoder port map (BIN_IN => rom_out, HEX_OUT => HEX2);
char1 : char_decoder port map (BIN_IN => std_logic_vector(address_uns), HEX_OUT => HEX4);
clock_slow <= Clock;
rom : rom_16x4_sync port map (clock => clock_slow, address => std_logic_vector(address_uns), rom_en => Rom_en, data_out => rom_out);
State_Memory : process (clock_slow, Reset)
begin
if (Reset = '0') then
current_state <= start;
elsif (clock_slow'event and clock_slow = '1') then
current_state <= next_state;
end if;
end process;
NEXT_STATE_LOGIC : process (current_state)
begin
case (current_state) is
when start => if (KEY0 = '0') then
next_state <= read_rom;
else next_state <= start;
end if;
when read_rom => if (address_counter = 15) then
next_state <= clear_addr;
else
address_counter <= address_counter + 1;
end if;
when clear_addr => next_state <= done;
address_counter <= 0;
when done => next_state <= done;
end case;
end process;
OUTPUT_LOGIC : process (current_state)
begin
case (current_state) is
when start => Rom_en <= '0';
addr_count_en <= '0';
addr_count_clr <= '0';
when read_rom => Rom_en <= '1';
addr_count_en <= '1';
addr_count_clr <= '0';
when clear_addr => Rom_en <= '0';
addr_count_en <= '1';
addr_count_clr <= '1';
when done => Rom_en <= '0';
addr_count_en <= '0';
addr_count_clr <= '0';
end case;
end process;
Address_Count : process (addr_count_en, addr_count_clr, clock_slow)
begin
if (clock_slow'event and clock_slow = '1') then
if (addr_count_en = '1') then
if (addr_count_clr = '1') then
address_uns <= "0000";
else
address_uns <= address_uns + 1;
end if;
end if;
end if;
end process;
address_uns <= to_unsigned(address_counter,4);
end architecture;
I commented on what I could see wrong with your code:
address_counter isn't clocked and is redundant. Remove the assignments and change the comparison to address_uns (which should also go into the sensitivity list) in process NEXT_STATE_LOGIC. Remove the concurrent signal assignment to address_uns following process Address_Counter. If processes Address_Count and OUTPUT_LOGIC are correct as well as rom_16x4_sync you should have something that works.
Well I had most the bits and pieces sitting around from other questions to gen a complete MCVE together with little effort mostly by copying and pasting and that gave:
As you can see that didn't work, and the reason why is that address_uns needs to be reset (it's default value is all 'U's).
Adding a reset gives:
So the gist of this is that your state machine was almost correct, it was missing the address counter in it's sensitivity list and had two address counters. Limiting that to one and resetting it so you weren't adding 1 to all 'U's shows your state machine is working.
And the code with all the fixes:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity char_decoder is
port (
bin_in: in std_logic_vector (3 downto 0);
hex_out: out std_logic_vector (6 downto 0)
);
end entity;
architecture dummy of char_decoder is
-- seven segment display
--
-- a
-- f b
-- g
-- e c
-- d
--
-- SEGMENT is defined (g downto a)
--
type segment7 is array (integer range 0 to 15) of
std_logic_vector (6 downto 0);
constant hex_to_segment: segment7 := (
"1000000", -- 0
"1111001", -- 1
"0100100", -- 2
"0110000", -- 3
"0011001", -- 4
"0010010", -- 5
"0000010", -- 6
"1111000", -- 7
"0000000", -- 8
"0011000", -- 9
"0001000", -- A
"0000011", -- b
"0111001", -- C
"0100001", -- d
"0000110", -- E
"0001110" -- F
);
begin
process (bin_in)
variable seg7_val: integer range 0 to 15;
begin
seg7_val := to_integer(unsigned(bin_in));
hex_out <= hex_to_segment(seg7_val);
end process;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity rom_16x4_sync is
port (
clock: in std_logic;
address: in std_logic_vector (3 downto 0);
rom_en: in std_logic;
data_out: out std_logic_vector(3 downto 0)
);
end entity;
architecture dummy of rom_16x4_sync is
type rom_array is array (0 to 15) of std_logic_vector(3 downto 0);
function fill_rom return rom_array is
variable ret_val: rom_array;
begin
for i in rom_array'reverse_range loop -- backward to i
ret_val(i) := std_logic_vector(to_unsigned(i,4));
end loop;
return ret_val;
end function;
constant rom: rom_array := fill_rom;
begin
process (clock)
begin
if rising_edge(clock) and rom_en = '1' then -- NO RESET
data_out <= rom(to_integer(unsigned(address)));
end if;
end process;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity top is
port (
clock: in std_logic;
reset: in std_logic;
sw: in std_logic_vector (1 downto 0); -- not used?
hex2, hex4: out std_logic_vector ( 6 downto 0);
key0: in std_logic
);
end entity;
architecture top_arch of top is
component char_decoder is
port (
bin_in: in std_logic_vector (3 downto 0);
hex_out: out std_logic_vector (6 downto 0)
);
end component;
component rom_16x4_sync is
port (
clock: in std_logic;
address: in std_logic_vector (3 downto 0);
rom_en: in std_logic;
data_out: out std_logic_vector(3 downto 0)
);
end component;
type state_type is (start, read_rom, clear_addr, done);
signal current_state,
next_state: state_type;
signal rom_en,
addr_count_clr,
addr_count_en: std_logic;
-- signal address_counter: integer range 0 to 15;
signal address_uns: unsigned (3 downto 0);
signal clock_slow: std_logic;
signal rom_out: std_logic_vector (3 downto 0);
begin
char:
char_decoder
port map (
bin_in => rom_out,
hex_out => hex2
);
char1:
char_decoder
port map (
bin_in => std_logic_vector(address_uns),
hex_out => hex4
);
clock_slow <= clock;
rom:
rom_16x4_sync
port map (
clock => clock_slow,
address => std_logic_vector(address_uns),
rom_en => rom_en, data_out => rom_out
);
state_memory:
process (clock_slow, reset)
begin
if reset = '0' then
current_state <= start;
elsif clock_slow'event and clock_slow = '1' then
current_state <= next_state;
end if;
end process;
next_state_logic:
-- process (current_state)
process (current_state, address_uns)
begin
case (current_state) is
when start =>
if key0 = '0' then
next_state <= read_rom;
else
next_state <= start;
end if;
when read_rom =>
if address_uns = 15 then
next_state <= clear_addr;
-- else
-- address_counter <= address_counter + 1;
end if;
when clear_addr => -- not a defined sequential logic inference
next_state <= done;
-- address_counter <= 0;
when done =>
next_state <= done;
end case;
end process;
output_logic:
process (current_state)
begin
case (current_state) is
when start =>
rom_en <= '0';
addr_count_en <= '0';
addr_count_clr <= '0';
when read_rom =>
rom_en <= '1';
addr_count_en <= '1';
addr_count_clr <= '0';
when clear_addr =>
rom_en <= '0';
addr_count_en <= '1';
addr_count_clr <= '1';
when done =>
rom_en <= '0';
addr_count_en <= '0';
addr_count_clr <= '0';
end case;
end process;
address_count:
process (addr_count_en, addr_count_clr, clock_slow)
begin
if reset = '0' then -- added reset
address_uns <= (others =>'0');
elsif clock_slow'event and clock_slow = '1' then
if addr_count_en = '1' then
if addr_count_clr = '1' then
address_uns <= "0000";
else
address_uns <= address_uns + 1;
end if;
end if;
end if;
end process;
-- address_uns <= to_unsigned(address_counter, 4);
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity top_tb is
end entity;
architecture foo of top_tb is
signal clock: std_logic := '0';
signal reset: std_logic := '1';
signal sw: std_logic_vector (1 downto 0) := "00";
signal hex2, hex4: std_logic_vector ( 6 downto 0);
signal key0: std_logic := '0';
begin
DUT:
entity work.top
port map (
clock => clock,
reset => reset,
sw => sw,
hex2 => hex2,
hex4 => hex4,
key0 => key0
);
CLK:
process
begin
wait for 5 ns;
clock <= not clock;
if now > 200 ns then
wait;
end if;
end process;
STIMULIS:
process
begin
wait for 1 ns;
reset <= '0';
wait for 10 ns;
reset <= '1';
wait for 10 ns;
wait;
end process;
end architecture;
The char_decoder I used should be fully functional. The ROM contents are simply dummied up.
I'm sending data to and A/D converter and I need the command data to be delayed at least 50ns from clk_19khz. Here is what I have so far.
How do I insert a delay of 50ns which is a requirement for the A/D between the clk_19khz and my first Dout bit to the A/D?
I'm using a Xilinx FPGA. Thanks for the help!
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity PSOL is
Port ( clk : in STD_LOGIC;
clk_19khz : OUT std_logic;
Dout :out std_logic);
end PSOL;
architecture Behavioral of PSOL is
signal temp : std_logic;
signal count : integer range 0 to 1301 := 0; --1301
signal temp2 : std_logic;
signal dcount : integer range 0 to 11 := 0; --
signal start : std_logic := '1'; -- indicates the start of
signal parity : std_logic := '1'; --used to varify data sent
signal stop : std_logic := '0'; --indicate when word/command has
--signal chip_select : bit :='1'; -- active low
begin
process (clk)
begin
if (clk' EVENT AND clk='1') then
if (count = 1301) then --1301
temp <= not(temp);
count <=0;
else
count <= count + 1;
end if;
end if;
end process;
clk_19khz <= temp;
temp2 <= temp;
process (temp2)
begin
If (temp2' EVENT and temp2 ='0') then
dcount <= dcount + 1;
parity <= '1';
stop <= '0';
start <='1';
if (dcount < 12 and start = '1' and stop = '0') then
CASE dcount is
when 1 => Dout <= start; -- need delay 50ns before this
when 2 => Dout <= '0';
when 3 => Dout <= '1';
when 4 => Dout <= '0';
when 5 => Dout <= '1';
when 6 => Dout <= '0';
when 7 => Dout <= '0';
when 8 => Dout <= '1';
when 9 => Dout <= '1';
when 10 => Dout <= parity;
when 11 => Dout <= '0';
when others => null;
end case;
end if;
end if;
--dcount <= 0;
--start <='1';
end process;
end Behavioral;
Your clock (50 MHz) has a period of 20 ns. So you'll need a modulo-3 counter to count a delay of at least 3 clock pulses which gives a delay of 60 ns.
Declarations:
signal delay_en : std_logic;
signal delay_us : unsigned(1 downto 0) := (others => '0');
signal delay_ov : std_logic;
Usage:
process(clk)
begin
if rising_edge(clk) then
if (delay_en = '1') then
delay_us <= delay_us + 1;
else
delay_us <= (others => '0');
end if;
end if;
end process;
delay_ov <= '1' when (delay_us = 2) else '0';
Your current implementation needs to drive delay_en while it's waiting for the timespan. If the delay is over, it emits the signal delay_ov (ov = overflow). This can be used by your solution to go on the in algorithm. Your code should also deassert delay_en, what clears the counter to 0.
I'm going to implement partial reconfiguration on virtex5 Xilinx Board. I've written 3 modules(top module and up-counter and down-counter) and created bit streams by Plan-ahead.The result is shown by 2 LEDs(up or down count). My problem is how to exchange counter partitions? or how to control icap by time or an external signal?
I prefer to don't use Microblaze so write state machine for icap as below:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_arith.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;
library UNISIM;
use UNISIM.VComponents.all;
Library UNIMACRO;
use UNIMACRO.vcomponents.all;
entity Main is
port(
Clk: in std_logic;
Output: out std_logic_vector(2 downto 0)
);
end Main;
architecture Behavioral of Main is
signal Q: std_logic_vector(47 downto 0);
signal Load, Clk1hz, Clk1 : std_logic;
signal Local : std_logic_vector(1 downto 0);
component ROM ------------------------------ ROM Component Decleration
port (
Clka: in std_logic;
Addra: in std_logic_vector(11 downto 0);
Douta: out std_logic_vector(31 downto 0));
end component; -------------------------------------------------------End
signal ROM_Address, ROM_Address_Init : std_logic_vector(11 downto 0); -------- ROM and ICAP Signals Decleration
signal ROM_Data : std_logic_vector(31 downto 0);
signal ICAP_Din, ICAP_Dout : std_logic_vector(31 downto 0);
signal ICAP_CE, ICAP_Clk, ICAP_Clk1, En, ROM_Clk, ROM_Clk1, ICAP_WR : std_logic; --------------------------------------End
begin
Clk1Hz <= Clk1;
process(clk)
begin
if (rising_edge(Clk)) then
if (Q=x"000005F5E100") then
Load <= '1';
Clk1 <= not Clk1;
else
Load <= '0';
end if;
end if;
end process;
Output(0) <= not(En);
Output(2 downto 1) <= not(Local);
----------------------------------------------------
----------------------------------------------------
U_UpDown: entity work.Counter
port map(
Clk => Clk1Hz, En => '1', Output => Local
);
----------------------------------------------------
----------------------------------------------------
U1 : COUNTER_LOAD_MACRO
generic map (
COUNT_BY => X"000000000001", -- Count by value
DEVICE => "VIRTEX5", -- Target Device: "VIRTEX5", "VIRTEX6", "SPARTAN6"
WIDTH_DATA => 48) -- Counter output bus width, 1-48
port map (
Q => Q, -- Counter output, width determined by WIDTH_DATA generic
CLK => CLK, -- 1-bit clock input
CE => '1', -- 1-bit clock enable input
DIRECTION => '1', -- 1-bit up/down count direction input, high is count up
LOAD => LOAD, -- 1-bit active high load input
LOAD_DATA => x"000000000000", -- Counter load data, width determined by WIDTH_DATA generic
RST => '0' -- 1-bit active high synchronous reset
);
--------------------------------------------
--------------------------------------------
process(Clk1Hz) -------------------------------------------- ROM and ICAP Modules and Related Codes
variable Count : integer range 0 to 6:=0;
begin
if (rising_edge(Clk1Hz)) then
Count := Count + 1;
if (Count = 2) then
En <= '1';
ROM_Address_Init <= conv_std_logic_vector(0,12);
else
En <= '0';
end if;
end if;
end process;
--------------------------------------------
--------------------------------------------
U_ROM: ROM
port map (Clka => ROM_Clk1, Addra => ROM_Address, Douta => ROM_Data);
BUFG_inst : BUFG
port map (
O => ROM_Clk1, -- Clock buffer output
I => ROM_Clk -- Clock buffer input
);
BUFG_inst1 : BUFG
port map (
O => ICAP_Clk1, -- Clock buffer output
I => ICAP_Clk -- Clock buffer input
);
ICAP_VIRTEX5_inst : ICAP_VIRTEX5
generic map (
ICAP_WIDTH => "X32") -- "X8", "X16" or "X32"
port map (
BUSY => open, -- Busy output
O => ICAP_Dout, -- 32-bit data output
CE => ICAP_CE, -- Clock enable input
CLK => ICAP_Clk1, -- Clock input
I => ICAP_Din, -- 32-bit data input
WRITE => ICAP_WR -- Write input
);
-- ICAP_Din(31 downto 8) <= x"000000"; -------------------------------End
U_ICAP_SM: block -------------------------------------
type State_Type is (State0, State00, State1, State2, State3, State4, State5, State6);
signal Pr_State, Nx_State : State_Type;
begin
Process(En,Clk)
begin
if (En = '0') then
Pr_State <= State0;
elsif (rising_edge(Clk)) then
Pr_State <= Nx_State;
end if;
end process;
process(Pr_State)
begin
case Pr_State is --*****
when State0 =>
Nx_State <= State00;
ROM_Address <= x"000";
ICAP_WR <= '1';
ROM_Clk <= '0';
ICAP_Clk <= '0';
ICAP_CE <= '1';
when State00 =>
Nx_State <= State1;
ICAP_WR <= '0';
when State1 =>
Nx_State <= State2;
ICAP_CE <= '0';
ROM_Clk <= '1';
when State2 =>
Nx_State <= State3;
ICAP_Din <= ROM_Data;
ROM_Clk <= '0';
when State3 =>
Nx_State <= State4;
ICAP_Clk <= '1';
when State4 =>
Nx_State <= State5;
ICAP_Clk <= '0';
when State5 =>
if (ROM_Address = conv_std_logic_vector(3134,12)) then
Nx_State <= State6;
ICAP_CE <= '1';
ROM_Address <= X"000";
else
Nx_State <= State1;
ROM_Address <= (ROM_Address + 1);
end if;
when State6 =>
ICAP_WR <= '1';
end case;
end process;
end Block U_ICAP_SM; -----------------------------------
end Behavioral;
I saved the bit stream (.coe file) of one of the counter (for example up-counter) in ROM. By default circuit is down counting, but when I exchange bit stream by icap (load .coe file of up-counter from ROM) nothing happens and circuit is counting down. (***** in the code)
how can I fix it?
i'm in the process of configuring an RS232 to USB cable with VHDL and i seem to have a problem. I don't know how to configure a dual-port RAM. I have attempted searching on answers to that and i found some code but i don't completely understand how to apply this code. This code can be found in this link --> http://www.asic-world.com/examples/vhdl/ram_dp_ar_aw.html.
Please help as soon as possible, i'm in desperate need of this information.
----------------------------------------------------------------------------------
-- Create Date : 14:06:22 12/08/2013
-- Designer Name : Sarin anand k
-- Module Name : UART - Behavioral
-- Project Name : RS232 transmitter
----------------------------------------------------------------------------------
-- spartan 3 starter kit
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use ieee.std_logic_unsigned.all;
library UNISIM;
use UNISIM.VComponents.all;
entity uart is
port(
sys_clk : in std_logic; --50Mhz
reset : in std_logic;
data_in : in std_logic_vector(7 downto 0); -- switch
load : in std_logic; --push button
Tx : out std_logic
);
end uart;
architecture Behavioral of uart is
type T_state is (IDLE,STORAGE,START, DATA, STOP);
-- baud rate = 115200, bit duration required is 1/115200 = 8680 ns
-- for a 50MHz clock, period is 20 ns. So each bit is 8680/20 = 434 clock cycles
constant bit_dur : std_logic_vector(15 downto 0) := X"01B3"; -- 434 clocks
constant start_bit : std_logic := '0';
constant stop_bit : std_logic := '1';
signal baud_cnt : std_logic_vector(23 downto 0) := X"000000"; -- 115200
signal baud_en : std_logic;
signal temp : std_logic_vector(7 downto 0);
signal baud_rate_cnt : std_logic_vector(7 downto 0):=(others => '0');
signal bit_cnt_start : std_logic;
signal baud_flag : std_logic;
signal state : T_state;
begin
-----------------------------------------------------------------------------------------------------
---- baud clock
------------------------------------------------------------------------------------------------------
baud_rate: process(sys_clk) begin
if rising_edge(sys_clk) then
if (reset = '1') then
baud_cnt <= X"000000";
baud_en <= '0';
end if;
if (baud_cnt = bit_dur)then
baud_en <= '1'; -- data in flag
baud_cnt <= X"000000";
elsif(bit_cnt_start = '1') then
baud_cnt<= baud_cnt + '1';
baud_en <= '0';
end if;
end if;
end process baud_rate;
---------------------------------------------------------------------------------------------------------------
-- baud clock counter
----------------------------------------------------------------------------------------------------------------
baud_counter: process(sys_clk) begin
if(rising_edge (sys_clk)) then
if(reset = '1') then
baud_rate_cnt <=( others => '0');
baud_flag <= '0';
end if;
if( baud_rate_cnt = "1000") then
baud_flag <= '1';
baud_rate_cnt <=( others => '0');
elsif( state = DATA and baud_en ='1') then
baud_rate_cnt <= baud_rate_cnt + '1';
baud_flag <= '0';
end if;
end if;
end process baud_counter;
--------------------------------------------------------------------------------------------------------------------
-- State machine to control the data flow
----------------------------------------------------------------------------------------------------------------------
control_flow: process (sys_clk) begin
if(rising_edge (sys_clk)) then
if (reset = '1') then
bit_cnt_start <= '0';
state <= IDLE;
end if;
case state is
when IDLE =>
state <= STORAGE;
when STORAGE =>
if (load = '1') then
state <= START;
bit_cnt_start <= '1';
end if;
when START =>
if (baud_en ='1') then
state <= DATA;
end if;
when DATA =>
if ((baud_en ='1') and (baud_flag = '1')) then
state <= STOP;
end if;
when STOP =>
if (baud_en = '1') then
state <= IDLE;
bit_cnt_start <= '0';
end if;
when others =>
state <= IDLE;
end case;
end if;
end process control_flow;
------------------------------------------------------------------------------------------------------------------------
-- Data Transmission
-------------------------------------------------------------------------------------------------------------------------
data_trans: process (sys_clk) begin
if (rising_edge(sys_clk)) then
if (reset = '1') then
temp <= (others => '0');
end if;
-- Data Mux
case state is
when IDLE =>
temp <= (others => '0');
when STORAGE =>
temp <= data_in;
when START =>
Tx <= start_bit;
when DATA =>
Tx <= temp(0);
if ( baud_en = '1') then
temp <= '0' & temp(7 downto 1) ;
Tx <= temp(0);
end if;
when STOP =>
Tx <= stop_bit;
when others =>
Tx <= '1';
end case;
end if;
end process data_trans;
end Behavioral;
I created each module and a test bench. each does exactly what its supposed to in the simulator. but when i attempt to synthesize i get the error "2170 - Unit VgaTest : the following signal(s) form a combinatorial loop: U1/Madd_divider_lut<1>" followed by the map process removing every single signal from the top level module (message 701) this leaves my device without any output (confirmed with oscilloscope)
I don't understand why it simulates and works fine, but then does this. any advice or information would be appreciated.
(using a mimas v2 with 100Mhz clock, on a spartan6 yes I know the clock is 25.000 mhz not 25.175)
ClockGen:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;
entity ClockGen is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
clkout : out STD_LOGIC);
end ClockGen;
architecture Behavioral of ClockGen is
signal divider : std_logic_vector(3 downto 0) := (others => '0');
begin
process(clk, rst)
begin
if (rst = '1') then
divider <= "0000";
else
divider <= divider + '1';
end if;
end process;
clkout <= divider(3);
end Behavioral;
VgaController:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity vgaController is
Port(
clk: in std_logic; -- pixel clock (25.175Mhz)
hsync: out std_logic;
vsync: out std_logic;
r: out std_logic_vector(3 downto 0);
g: out std_logic_vector(3 downto 0);
b: out std_logic_vector(2 downto 0)
);
end vgaController;
architecture Behavioral of vgaController is
-- horizontal timing(line)
constant hva: integer := 640; -- visible area
constant hfp: integer := 16; -- front porch
constant hsp: integer := 96; -- sync pulse
constant hbp: integer := 48; -- back porch
-- vertical timing
constant vva: integer := 480; -- visible area
constant vfp: integer := 10; -- front porch
constant vsp: integer := 2; -- sync pulse
constant vbp: integer := 32; -- back porch
signal HPOS: integer range 0 to 800 := 0;
signal VPOS: integer range 0 to 525 := 0;
begin
process (clk)
begin
if (rising_edge(clk)) then
-- update the position counters
if (HPOS < (hva+hfp+hsp+hbp)) then -- are we within the horizontal area?
HPOS <= HPOS + 1;
else
HPOS <= 0;
if (VPOS < (vva+vfp+vsp+vbp)) then -- are we within vertical area?
VPOS <= VPOS + 1;
else
VPOS <= 0;
end if;
end if;
-- update the sync signals
if (HPOS > (hva+hfp) and HPOS < (hva+hfp+hsp)) then -- horiz sync
hsync <= '0';
else
hsync <= '1';
end if;
if (VPOS > (vva+vfp) and VPOS < (vva+vfp+vsp)) then -- vertical sync
vsync <= '0';
else
vsync <= '1';
end if;
-- TEMP -- SET OUR PIXELS (this will be replaced with actual driver code later)
if ((HPOS > hva) or (VPOS > vva)) then
-- blank signal
R <= (others => '0');
G <= (others => '0');
B <= (others => '0');
else
-- blue background
R <= (others => '0');
G <= (others => '0');
B <= (others => '1');
-- white cross hair
if ((HPOS > 475 and HPOS < 485) or (VPOS > 280 and VPOS < 290)) then
R <= (others => '1');
G <= (others => '1');
B <= (others => '1');
end if;
end if;
end if;
end process;
end Behavioral;
and VgaTest (topmost module):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity VgaTest is
Port(
clk: in std_logic;
HSYNC: out std_logic;
VSYNC: out std_logic;
r: out std_logic_vector(3 downto 0);
g: out std_logic_vector(3 downto 0);
b: out std_logic_vector(2 downto 0)
);
end VgaTest;
architecture Behavioral of VgaTest is
component ClockGen
Port(
clk : IN std_logic;
rst : IN std_logic;
clkout : OUT std_logic
);
end component;
component vgaController
Port(
clk : IN std_logic;
hsync : OUT std_logic;
vsync : OUT std_logic;
r : OUT std_logic_vector(3 downto 0);
g : OUT std_logic_vector(3 downto 0);
b : OUT std_logic_vector(2 downto 0)
);
end component;
signal clktmp: std_logic;
signal out_hsync: std_logic := '0';
signal out_vsync: std_logic := '0';
signal out_r: std_logic_vector(3 downto 0);
signal out_g: std_logic_vector(3 downto 0);
signal out_b: std_logic_vector(2 downto 0);
begin
U1: ClockGen Port map (
clk => clk,
rst => '0', -- reset is not being used, so hardwire it low
clkout => clktmp
);
U2: vgaController Port map (
clk => clktmp,
hsync => out_hsync,
vsync => out_vsync,
r => out_r,
g => out_g,
b => out_b
);
HSYNC <= out_hsync;
VSYNC <= out_vsync;
r <= out_r;
g <= out_g;
b <= out_b;
end Behavioral;
I'm really thinking its likely a newbie issue, but I just cant seem to figure out why.
edited to remove the similarity to another question. i will be flagging as solved, but the issue that was pointed out was that my clockgen process was not actually being clocked. by changing it to have
elsif(rising_edge(clk)) then
...
resolved the synthesizers complaints. not yet tested on real hardware but i see no reason it will still fail.
as per user1155120 the issue was the clock. it would synthesize out the entirety of the net because it never generated a clock. here is the fix
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;
entity ClockGen is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
clkout : out STD_LOGIC);
end ClockGen;
architecture Behavioral of ClockGen is
signal divider : std_logic_vector(3 downto 0) := (others => '0');
begin
process(clk, rst)
begin
if (rst = '1') then
divider <= "0000";
elsif (rising_edge(clk)) then
divider <= divider + '1';
end if;
end process;
clkout <= divider(3);
end Behavioral;
using this it displays fine providing the monitor will support 25Mhz flat. the clock was replaced with a PLL setup to give me exactly 25.175 to make it work on any monitor (at least that i've tried so far)