0

また私です!最初に言っておきたいのは、私は数日前に VHDL を学びましたが、これに関してはまったくの初心者なので、ばかげた間違いを犯しがちです。どんな提案も素晴らしいでしょう。メモリ コントローラーとして使用できるモジュールの VHDL コードを作成しました。

これが私のコードです:

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity memory_controller is
port(clk: in std_logic;
     reset: in std_logic;
     bus_id: in std_logic_vector(7 downto 0);
     read_write, burst: in std_logic;
     ready: in std_logic;
     oe, we: out std_logic;
     addr_1, addr_2: out std_logic_vector(7 downto 0)
     );
end memory_controller;
architecture behavioral of memory_controller is
    type statetype is (idle, decision, wr, rd1, rd2, rd3, rd4);
    signal present_state, next_state : statetype;
    signal addr_int : integer range 0 to (2**addr_1'length)-1;
    begin
    Synch_reset: process(clk)
    begin
        if (rising_edge(clk)) then
            if (reset ='0') then
                present_state <= next_state;  
            else
                present_state <= idle;   
            end if;
        end if;
    end process;  
    decision_logic: process(present_state, read_write, ready, burst)
    begin
        case present_state is
            when idle => 
                oe <= '0'; we <= '0'; addr_int <= 0;
                addr_1 <= std_logic_vector(to_unsigned(addr_int, addr_1'length));
                addr_2 <= std_logic_vector(to_unsigned(addr_int, addr_2'length));
                if(bus_id = "11110011") then
                    next_state <= decision;
                else
                    next_state <= idle;
                end if;
            when decision =>
                if (read_write = '1') then 
                    next_state <= rd1;
                else 
                    next_state <= wr;
                end if;
            when wr =>
                we <= '1';
                if (ready = '1') then 
                    next_state <= idle;
                else
                    next_state <= wr;
                end if;
            when rd1 =>
                oe <= '1';
                if(ready = '0') then
                    next_state <= rd1;
                else
                    if(burst = '0') then
                        next_state <= idle;
                    else 
                        next_state <= rd2;
                        addr_int <= addr_int + 1;
                addr_1 <= std_logic_vector(to_unsigned(addr_int, addr_1'length));
                addr_2 <= std_logic_vector(to_unsigned(addr_int, addr_2'length));
                    end if;
                end if;
            when rd2 =>
                oe <= '1';
                if(ready = '1') then
                    next_state <= rd3;
                    addr_int <= addr_int + 1;
                addr_1 <= std_logic_vector(to_unsigned(addr_int, addr_1'length));
                addr_2 <= std_logic_vector(to_unsigned(addr_int, addr_2'length));
                else
                    next_state <= rd2;
                end if;
            when rd3 =>
                oe <= '1';
                if(ready = '1') then 
                    next_state <= rd4;
                    addr_int <= addr_int + 1;
                addr_1 <= std_logic_vector(to_unsigned(addr_int, addr_1'length));
                addr_2 <= std_logic_vector(to_unsigned(addr_int, addr_2'length));
                else
                    next_state <= rd3;
                end if;
            when rd4 =>
                oe <= '1';
                if(ready = '1') then 
                    next_state <= idle;
                else 
                    next_state <= rd4;
                end if;
         end case;
     end process;
end behavioral;

これが私のテストベンチです:

Library IEEE;
USE IEEE.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity memory_controller_tb is
end memory_controller_tb;
architecture test of memory_controller_tb is
component memory_controller
port(clk: in std_logic;
     reset: in std_logic;
     bus_id: in std_logic_vector(7 downto 0);
     read_write, burst: in std_logic;
     ready: in std_logic;
     oe, we: out std_logic;
     addr_1, addr_2: out std_logic_vector(7 downto 0)
     );
end component;
signal clk: std_logic;
signal reset: std_logic;
signal read_write, burst, oe, we: std_logic;
signal addr_1, addr_2: std_logic_vector(7 downto 0);
signal ready: std_logic;
signal bus_id: std_logic_vector(7 downto 0);
signal StopClock : boolean := FALSE;
begin
UUT :memory_controller
port map( clk => clk,
          reset => reset,
          bus_id => bus_id,
          read_write => read_write,
          burst => burst,
          ready => ready,
          oe => oe,
          we => we,
          addr_1 => addr_1,
          addr_2 => addr_2);
clk_process: process
begin
while not StopClock loop
clk <= '0';
wait for 5 ns;
clk <= '1';
wait for 5 ns;
end loop;
end process clk_process;
stim: process is
begin
reset <= '1', '0' after 50 ns;
bus_id <= "11110011";
wait for 5 ns;
read_write <= '0';
wait for 5 ns;
ready <= '1';
bus_id <= "11110011";
wait for 5 ns;
read_write <= '1';
assert (ready <='1' and burst <= '1')
report "Illegal state"
severity error;
assert (ready <= '1' and burst <='0')
report "Illegal state"
severity error;
wait for 5 ns;
ready <= '0';
wait for 5 ns;
burst <= '0';
wait for 5 ns;
ready <= '1';
wait for 5 ns;
burst <= '1';
wait for 5 ns;
ready <= '0';
wait for 5 ns;
ready <= '1';
wait for 5 ns;
ready <= '1';
end process;
end test;

configuration CFG_memory_controller of memory_controller_tb is
    for test
        for UUT : memory_controller
        end for;
    end for;
end;

バーストがアサートされると、Ready のアサート時に read1 read2 read3 および read4 を通過する必要があり (バースト = 1 の場合、Ready が 1 の場合は read 2、read 3、read 4 に進む必要があります)、アイドル状態に入ってはなりません。リセットがその間のいつでも 0 になった場合。しかし、それは私にとってはそうです。リセットに依存しないようにプログラムを変更するにはどうすればよいですか?

また、アドレスがリセットされてアイドル状態に戻る場合、アドレスは 0 にリセットされません。コードを変更しようとすると、複数の場所からアドレスをアサートしようとしていたと表示されます。

また、私のテスト ベンチ作成スキルは最低だと思います。従うべき規則やガイドラインはありますか、それとも直感を養う必要がありますか?

ありがとう!

4

1 に答える 1

0

組み合わせループがあります。組み合わせプロセスで信号を読み書きするため、addr_intあらゆる種類の問題が発生します。信号next_addr_intを作成してそれをクロック プロセスに割り当てるか、すべてを 1 つのクロック プロセスに配置します。

コードに関するその他の問題:

  • std_logic_arithstd_logic_unsigned推奨です。ieee.numeric_std代わりに使用してください。
  • このような変換は、コードを理解しにくくします:代わりに代わりにaddr_1 <= std_logic_vector(to_unsigned(addr_int, addr_1'length));使用します。unsignedstd_logic_vector
  • あなたのリセット句では、あなたが をチェックするので、人々はリセットがアクティブローであると想定しますreset = '0'。代わりに、 andの部分をチェックしreset = '1'て逆にします。ツールはコーディング スタイルを気にしないと思いますが、人間を混乱させます。ifelse
于 2012-10-17T08:51:02.337 に答える