导航: 老古网老古论坛XMOS公共讨论区XMOS开源项目区单片机程序设计嵌入式系统广告区域
→[讨论]终于解决了

* 105814: [讨论]状态机

   vfdff 
vfdff发表的帖子 

 [讨论]终于解决了
原来程序读取的时候,第一个周期上的地址址没有有效赋值,也就是必须延迟一个时钟后地址线上数据才有效,如下:
--  5.5  16:36
--  地址信号进入必须至少维持两个时钟周期   5.6
--  5 个时钟周期完成数据的存取

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;

ENTITY ram4 IS
 PORT (
  address_a  : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
  address_b  : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
  address_c  : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
  address_d  : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
  clock   : IN STD_LOGIC ;
  data_a  : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
  data_b  : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
  data_c  : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
  data_d  : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
  wren  : IN STD_LOGIC  := '1';
  q_a  : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
  q_b  : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
  q_c  : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
  q_d  : OUT STD_LOGIC_VECTOR (31 DOWNTO 0); 
  flag : OUT STD_LOGIC  := '0'-- 标志存取操作完成
 );
END ram4;

ARCHITECTURE SYN OF ram4 IS

 component ram2
 PORT (
  address_a  : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
  address_b  : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
  clock  : IN STD_LOGIC ;
  data_a  : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
  data_b  : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
  wren_a  : IN STD_LOGIC  := '1';
  wren_b  : IN STD_LOGIC  := '1';
  q_a  : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
  q_b  : OUT STD_LOGIC_VECTOR (31 DOWNTO 0)
 );
 end component;
 
 signal address_a_sig : STD_LOGIC_VECTOR (7 DOWNTO 0) := address_a;
 signal address_b_sig : STD_LOGIC_VECTOR (7 DOWNTO 0) := address_b;
 signal data_a_sig : STD_LOGIC_VECTOR (31 DOWNTO 0);
 signal data_b_sig : STD_LOGIC_VECTOR (31 DOWNTO 0);
 signal q_a_sig : STD_LOGIC_VECTOR (31 DOWNTO 0);
 signal q_b_sig : STD_LOGIC_VECTOR (31 DOWNTO 0);
 
 SIGNAL present_state: STD_LOGIC_VECTOR(2 DOWNTO 0):= "000";
 --SIGNAL processing : STD_LOGIC := '0';
 
begin

 ram2_inst : ram2 -- 需要两个时钟周期
 PORT MAP (
  address_a=>   address_a_sig,
  address_b=>   address_b_sig,
  clock  =>   clock,
  data_a  =>   data_a_sig,
  data_b  =>   data_b_sig,
  wren_a  =>   wren, -- 共用一个wren信号
  wren_b  =>   wren, -- 使两个port同时读写
  q_a    =>   q_a_sig,
  q_b    =>   q_b_sig
 );


    state_fb :process(clock) 
    begin
        if(clock'event and clock = '1') then
   --if (processing='1') then
         case present_state is
            when "000" =>          -- 前两个时钟赋地址值
                    address_a_sig   <= address_a;
     address_b_sig   <= address_b;
     data_a_sig      <= data_a;
     data_b_sig      <= data_b;
     flag            <= '0';
     present_state   <= present_state + "1";
            when "001" =>  
                    address_a_sig   <= address_c;
     address_b_sig   <= address_d;
     data_a_sig      <= data_c;
     data_b_sig      <= data_d;
     flag            <= '0';
     present_state   <= present_state + "001";
            when "010" =>  
     flag            <= '0';
     present_state   <= present_state + "001";  -- ???
   when "011" =>    -- 后两个时钟读取对应位置的数据
                 --q_c      <= (others=>  'Z');--q_a_sig;--
     --q_d      <= (others=>  'Z');
     address_a_sig   <= address_a;
     address_b_sig   <= address_b;
     q_a      <= q_a_sig;
     q_b      <= q_b_sig;
     flag            <= '0';
     present_state   <= present_state + "001"; 
   when "100" =>    -- 后两个时钟读取对应位置的数据
                 --q_a      <= (others=>  'Z');--q_a_sig;--
     --q_b      <= (others=>  'Z');
     address_a_sig   <= address_c;
     address_b_sig   <= address_d;
     q_c      <= q_a_sig;
     q_d      <= q_b_sig;
     flag     <= '1';           -- 存取操作结束
     present_state   <= "000";
   when others =>   present_state   <= "000";
         end case;
   --end if;
 end if;
 
    end process state_fb;

END SYN;
如果有更好的解决方案,希望大家提出

发表时间:2007年5月13日9:09:08

  
回复该帖

本主题共有 2 帖,分页:>>>>>该主题的所有内容[2]条

 *树形目录 只列出部分跟帖的标题以及简单的摘要信息 该主题的部分跟帖如下:

[上一篇帖子]:坚决同意原来是每个单片机有自己特有的编译器[em08]
[下一篇帖子]:请EMAIL万年历的程序给我请EMAIL万年历的程序给我 zrg999@163.com BR