Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
21613 Discussions

CPLD VHDL problem

Altera_Forum
Honored Contributor II
1,606 Views

HI, 

I am trying to understand the operation of the following VHDL code. 

The cpld EPM2210 is attached to a processor bus (d0-d15 and A0-A15). 

When I do a double read 'word aligned' address range 0xXXXXX40 to 0xXXXXXX5A 

I get:  

0xXXXXXX52 = 2357 2357 

0xXXXXXX54 = 5678 5678 

0xXXXXXX54 = EB67 EB67 

0xXXXXXX58 = 08FC 08FC 

0xXXXXXX5A = C438 C438 

 

At address 0xXXXXXX58 I expected 1267 and then F23C but I get 08FC and 08FC 

WHY!!!! 

 

Any help will be appreciated. 

 

==================================== 

library IEEE; 

use IEEE.std_logic_1164.all; 

use ieee.std_logic_arith.all; 

use IEEE.std_logic_unsigned.all; 

 

entity Top is 

port ( 

 

-----------------------------------------------------------------------------------------------------  

-- MICROCONTROLLER BUS 

----------------------------------------------------------------------------------------------------- 

clk : in std_logic; 

reset_n : in std_logic;  

proc_cs2_n : in std_logic; 

proc_rw_n : in std_logic; 

proc_oe_n : in std_logic; 

 

proc_addr : in std_logic_vector(17 downto 0); 

proc_data : inout std_logic_vector(15 downto 0); 

);  

 

end Top; 

 

architecture Structure of Top is 

 

--3631 

--4862 

--32c5 

--35a9 

--3072 

constant CPLD_Version_word: ROM_Array2 := ( 

0 => "0011011000110001",-- Suppose ROM has  

2 => "0100100001100010", -- prestored value 

4 => "0011001011000101", -- like this table 

6 => "0011010110101001", -- like this table 

8 => "0011000001110010", -- like this table 

OTHERS => "1111111111111111" -- 

);  

 

---------------------------------------------- 

-- states for reading fifo 24 bits 

---------------------------------------------- 

type read_fifo_24_bits is ( 

idle_state, 

read_top_16);  

 

 

signal state_rd_fifo : read_fifo_24_bits; 

 

-------------------------------------------------------------------------------- 

-------------------------------------------------------------------------------- 

 

begin 

 

-------------------------------------------------------------------------------- 

-- main process 

-------------------------------------------------------------------------------- 

 

process(reset_n, clk,state_rd_fifo,  

proc_data(15 downto 0),  

proc_addr(15 downto 0),  

proc_cs2_n,  

proc_rw_n, 

 

 

-------------------------------------------------------------------------------- 

-- variable must be here 

-------------------------------------------------------------------------------- 

 

variable state_fifo: integer range 0 to 4:= 0; 

 

begin 

 

 

-------------------------------------------------------------------------------- 

-- main reset 

-------------------------------------------------------------------------------- 

 

if reset_n='0' then 

 

proc_data <= "ZZZZZZZZZZZZZZZZ"; 

pwm_data0 <= "0000000000000000"; 

port_out11 <= "00000011"; -- for serial port comms 

state_fifo := 0; 

 

 

-------------------------------------------------------------------------------- 

-- start decode chip select and decode address input with a READ 

--------------------------------------------------------------------------------  

 

elsif (proc_cs2_n='0' and proc_rw_n='1' ) then 

 

case proc_addr(15 downto 0) is  

when "0000001100100000" =>proc_data(15 downto 0) <=  

CPLD_Version_word(conv_integer(proc_addr(3 downto 0))); 

when "0000001100100010"=>proc_data(15 downto 0) <=  

CPLD_Version_word(conv_integer(proc_addr(3 downto 0))); 

when "0000001100100100"=>proc_data(15 downto 0) <=  

CPLD_Version_word(conv_integer(proc_addr(3 downto 0))); 

when "0000001100100110"=>proc_data(15 downto 0) <=  

CPLD_Version_word(conv_integer(proc_addr(3 downto 0))); 

when "0000001100101000"=>proc_data(15 downto 0) <=  

CPLD_Version_word(conv_integer(proc_addr(3 downto 0)));  

 

when "0000000001010010" => proc_data (15 downto 0) <= X"2357";  

when "0000000001010011" => proc_data (15 downto 0) <= X"5678";  

when "0000000001010100" => proc_data (15 downto 0) <= X"eb67";  

when "0000000001010101" => proc_data (15 downto 0) <= X"e8fd";  

when "0000000001010110" => proc_data (15 downto 0) <= X"1ba5";  

when "0000000001011000" =>  

 

if(state_fifo = 0) then 

proc_data (15 downto 0) <= X"1267";  

state_fifo := 1; 

else  

proc_data (15 downto 0) <= X"abcd"; 

state_fifo := 1; 

end if;  

 

if(state_fifo = 1) then 

proc_data (15 downto 0) <= X"f23c";  

state_fifo := 2; 

else  

proc_data (15 downto 0) <= X"2784"; 

state_fifo := 2; 

end if; 

 

if(state_fifo = 2) then 

proc_data (15 downto 0) <= X"982b"; 

state_fifo := 0; 

else  

proc_data (15 downto 0) <= X"08fc"; 

state_fifo := 0; 

end if; 

 

 

when "0000000001011010" =>  

proc_data (15 downto 0) <= X"c438"; 

 

when others =>  

proc_data (15 downto 0) <= "ZZZZZZZZZZZZZZZZ"; 

end case; 

end if; 

end process;
0 Kudos
5 Replies
Altera_Forum
Honored Contributor II
880 Views

 

--- Quote Start ---  

At address 0xXXXXXX58 I expected 1267 and then F23C but I get 08FC and 08FC 

WHY!!!! 

--- Quote End ---  

 

 

Look sharp. According to your code, either X"982b" or X"08fc" are send. Only the code starting with if(state_fifo = 2) then is active. 

 

I also noticed, that the CPLD will possibly drive the bus, although not addressed. The output is only correctly tri-stated, if an "others" address is omitted before cs or rd are deasserted. Otherwise the last output word is hold permanently.
0 Kudos
Altera_Forum
Honored Contributor II
880 Views

Thanks FvM, 

Your right I need to open my eyes and wakeup!! 

 

I changed the code so that at the same address (0xxxxxx42) I could read in 24 alternative words. i.e. in this case 24 off (0x1234 and 0x789a). 

 

Can anyone think of why this code does not do this simple task. 

 

when "0000000001000010" => -- read 24 double words 

case state_rd_fifo is  

when idle_state => 

fifo_enable_read <= '1'; 

proc_data (15 downto 0) <= X"1234"; 

fifo_enable_write <= '0'; 

state_rd_fifo <= read_top_16; 

 

when read_top_16 => 

end_fifo_24_words:= end_fifo_24_words+1; 

state_rd_fifo <= idle_state; 

proc_data (15 downto 0) <= "789a; 

fifo_enable_read <= '0'; 

if end_fifo_24_words >= 24 then 

state_rd_fifo <= idle_state; 

end_fifo_24_words:= 0; 

end if; 

when others =>  

state_rd_fifo <= idle_state; 

end_fifo_24_words:= 0; 

proc_data (15 downto 0) <=  

"ZZZZZZZZZZZZZZZZ"; 

end case; 

 

 

when others => proc_data (15 downto 0) <=  

"ZZZZZZZZZZZZZZZZ"; 

end case;
0 Kudos
Altera_Forum
Honored Contributor II
880 Views

I would primarly ask what kind of process and trigger condition is including the FIFO counter and assignments of state_rd_fifo. A counter or a state variable register can only work under a clock edge sensitive condition, e.g if rising_edge(clk).

0 Kudos
Altera_Forum
Honored Contributor II
880 Views

Here is the code I am trying to to get to work: 

I am interested in the read condition when state_rd_fifo changes state: 

 

 

process(reset_n,clk,state_rd_fifo,  

proc_data(15 downto 0),  

proc_addr(15 downto 0),  

proc_cs2_n,  

proc_rw_n, 

state_rd_fifo) 

 

variable end_fifo_24_words : integer range 0 to 30 := 0; 

 

begin 

 

-------------------------------------------------------------------------------- 

-- main reset 

-------------------------------------------------------------------------------- 

 

if reset_n='0' then 

 

proc_data <= "ZZZZZZZZZZZZZZZZ"; 

state_rd_24bits <= idle_state; 

read_uart_24 <= '0';  

fifo_enable_read <= '0'; 

fifo_enable_write <= '0'; 

end_fifo_24_words := 0; 

state_rd_fifo <= state1; 

 

-------------------------------------------------------------------------------- 

-- start decode chip select and decode address input with a WRITE 

-------------------------------------------------------------------------------- 

elsif rising_edge(clk) then 

 

if (proc_cs2_n='0' and proc_rw_n='0') then 

case proc_addr(15 downto 0) is 

 

when "0000000000001110" =>  

case state_wr_24bits is 

when write_byte_1 => 

temp_word_24_0(23 downto 8) <= proc_data (15 downto 0); 

state_wr_24bits <= write_byte_2; 

 

when write_byte_2=> 

temp_word_24_1(23 downto 8) <= proc_data (15 downto 0); 

 

if(tx_ready_0 ='1') then -- now write the 24 bits to uart 

start_tx_0 <= '1'; 

tx_data_register_24bit_0 <= temp_word_24_1(23 downto 8) & 

temp_word_24_1(7 downto 0); 

tx_write0 <='1' ; 

state_wr_24bits <= write_byte_1; 

end if; 

end case; 

 

-------------------------------------------------------------------------------- 

-- start decode chip select and decode address input with a READ 

--------------------------------------------------------------------------------  

 

elsif (proc_cs2_n='0' and proc_rw_n='1' ) then 

 

case proc_addr(15 downto 0) is  

 

when "0000000001010010" => proc_data (15 downto 0) <= X"2357";  

when "0000000001010011" => proc_data (15 downto 0) <= X"5678";  

when "0000000001010100" => proc_data (15 downto 0) <= X"eb67";  

when "0000000001010101" => proc_data (15 downto 0) <= X"e8fd";  

when "0000000001010110" => proc_data (15 downto 0) <= X"1ba5";  

when "0000000001011000" =>  

 

 

case state_rd_fifo is 

when state1 => 

proc_data (15 downto 0) <= X"1267"; --temp_word_24_0(23 downto 8); 

state_rd_fifo <= state2; 

 

when state2 => 

proc_data (15 downto 0) <= X"f23c"; --temp_word_24_0(23 downto 8); 

state_rd_fifo <= state1; 

when others => 

proc_data (15 downto 0) <= "ZZZZZZZZZZZZZZZZ"; 

end case;  

 

 

when "0000000001011010" => proc_data (15 downto 0) <= X"c438"; 

 

when others => proc_data (15 downto 0) <= "ZZZZZZZZZZZZZZZZ"; 

end case; 

 

 

end if; 

 

end process;
0 Kudos
Altera_Forum
Honored Contributor II
880 Views

It's not clear to me, what the code is expected to do. As coded, the state machine advances on every clock cycle while read is active. The result depends on the relation of clock and processor bus timing.

0 Kudos
Reply