- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page