1

我正在尝试实现以下移位寄存器

entity MyShiftRegister is
    port(
        clock:   in  std_logic;
        DataIn:  in  std_logic_vector (9 downto 0); 
        Left:    in  std_logic;  --synchronous left rotate
        Right:   in  std_logic;  --synchronous right rotate
        Load:    in  std_logic;  --synchronous parallel load
        Clear:   in  std_logic;  -- synchronous clear
        DataOut: out std_logic_vector (9 downto 0);     

这是我到目前为止所拥有的


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity question2 is
    Port (
        led: buffer std_logic_vector (9 downto 0);
        clk: in std_logic;
        btnu: in std_logic;
        btnL: in std_logic;
        btnR: in std_logic ; 
        btnD: in std_logic;
        btnC: in std_logic 
     );
end question2;

architecture Behavioral of question2 is
    constant active: std_logic :='1';
    constant inactive: std_logic :='0';

    constant step_zero:  std_logic_vector(9 downto 0) :="0000000000";  
    constant step_one:   std_logic_vector(9 downto 0) :="0000000001";
    constant step_two:   std_logic_vector(9 downto 0) :="0000000010"; 
    constant step_three: std_logic_vector(9 downto 0) :="0000000100";
    constant step_four:  std_logic_vector(9 downto 0) :="0000001000";
    constant step_five:  std_logic_vector(9 downto 0) :="0000010000";
    constant step_six:   std_logic_vector(9 downto 0) :="0000100000";    
    constant step_seven: std_logic_vector(9 downto 0) :="0001000000";
    constant step_eight: std_logic_vector(9 downto 0) :="0010000000";
    constant step_nine:  std_logic_vector(9 downto 0) :="0100000000";
    constant step_ten:   std_logic_vector(9 downto 0) :="0100000000";

    signal DataIn: std_logic_vector (9 downto 0):= "1111111111";  
    signal Load: std_logic := btnD;
    signal Reset: std_logic; 
    signal Left: std_logic:= btnL;
    signal Right: std_logic:= btnR;
    signal DataOut: std_logic_vector := led (9 downto 0);
    signal Clear: std_logic:= btnU;
    signal speed_enable: std_logic; 
begin
    SpeedControl: process (clk)
        variable counter: integer range 0 to 10000000;
    begin
        speed_enable<=not active;  
        if Reset = Active then
            counter:= 0; 
        elsif (rising_edge (clk)) then 
            counter := counter + 1; 
            if (counter=10000000) then 
                speed_enable<= Active; 
                counter:=0; 
            end if; 
        end if; 
    end process; 

    shiftregister: process(clk, clear)
    begin
        if rising_edge (clk) then 
            if clear= active then 
                DataOut <= (others => '0');  
            elsif load = active then 
                DataOut <= DataIn ; 
            elsif Left = active then 
                DataOut <= DataOut(8 downto 0) & "1" ;
                if DataOut = "1000000000" then 
                    clear <= active;   
                elsif Right = active then 
                    DataOut <= DataOut (9 downto 1) & "1" ;
                    if DataOut = "0000000001" then 
                        clear <= active; 
                    end if; 
                end if; 
            end if; 
        end if;  
end process;

with DataOut select
    led <= step_one   when "0000",
           step_two   when "0001",
           step_three when "0010",
           step_four  when "0011",
           step_five  when "0100",
           step_six   when "0101",
           step_seven when "0110",
           step_eight when "0111",
           step_nine  when "1000", 
           step_ten   when "1001", 
           step_zero  when others;     
end Behavioral;

我如何准确地左右旋转位并将其绑定到我的 LED 输出。我正在考虑使用一个计数器,只是递增和递减以向左或向右移位,但我不确定这是否仍会被视为移位寄存器。

谢谢

4

1 回答 1

1

开始:

constant step_nine:  std_logic_vector(9 downto 0) :="0100000000";
constant step_ten:   std_logic_vector(9 downto 0) :="0100000000";

是不正确的。它应该是

constant step_nine:  std_logic_vector(9 downto 0) :="0100000000";
constant step_ten:   std_logic_vector(9 downto 0) :="1000000000";

但无论如何,这种方法很容易出错。让我们简化一下:

process(sel)
    variable selected_led : natural;
begin
    led <= (others => '0');
    selected_led := to_integer(unsigned(sel));
    if selected_led < led'length then
        led(selected_led) <= '1';
    end if;
end process;

如果led(selected_led) <= '1';无法合成,您可能必须将其更改为

for i in 0 to led'length-1 loop
    if (i = selected_led) then
        led(i) <= '1';
    end if;
end loop;

至于使用buffer端口。不。最好只使用inor out。如果要读取out端口,请使用 VHDL-2008 编译,或在两者之间使用临时信号。

然后注意rightandleft是 VHDL 中的关键字。你不应该使用它们

你想要的是非常简单和基本的 VHDL。示例(使用 VHDL-2008):

process(clock)
begin
    if rising'edge(clock) then
        if clear = '1' then
            data_out <= (others => '0');
        elsif load = '1' then
            data_out <= data_in;
        elsif right_rotate = '1' then
            data_out <= data_out(0) & data_out(data_out'length-1 downto 1);
        elsif left_rotate = '1' then
            data_out <= data_out(data_out'length-2 downto 0) &
                data_out(data_out'length-1);
        end if;
    end if;
end process;
于 2017-03-26T13:06:49.123 回答