Схема параметрического деления VHDL - Книга: Прототипирование FPGA на примерах VHDL, Понг Чу - PullRequest
0 голосов
/ 18 января 2019

Я пытаюсь следовать примеру из моей книги по VHDL. Его имя - прототипирование ПЛИС по примерам VHDL, Понг Чу. В главе 6, листинг 5 приведен пример схемы делителя. Я понял общую идею операции деления. Для проверки модуля я написал тестовый стенд и увидел, что он не работает должным образом. Если бы кто-нибудь мог объяснить мне, где проблема, я был бы очень признателен. Вот коды модуля и тестового стенда. Модуль:

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

entity Divider is
generic(W:      integer := 8;
        CBIT:   integer := 4 );
Port ( clk, reset :         in STD_LOGIC;
       start :              in STD_LOGIC;
       dvsr, dvnd :         in STD_LOGIC_VECTOR (W-1 downto 0);
       ready, done_tick :   out STD_LOGIC;
       quo, rmd :           out STD_LOGIC_VECTOR (W-1 downto 0));
end Divider;

architecture Behavioral of Divider is

type state_type is              (idle, op, last, done);
signal state_reg, state_next:   state_type;
signal rh_reg, rh_next:         UNSIGNED(W-1 downto 0)          := (others => '0');
signal rl_reg, rl_next:         STD_LOGIC_VECTOR(W-1 downto 0)  := (others => '0');
signal rh_temp:                 UNSIGNED(W-1 downto 0)          := (others => '0');
signal d_reg, d_next:           UNSIGNED(W-1 downto 0)          := (others => '0');
signal n_reg, n_next:           UNSIGNED(CBIT-1 downto 0)       := (others => '0');
signal q_bit:                   STD_LOGIC;

begin
-- FSMD State and Data Registers
process(clk, reset)
begin
    if reset = '1' then
        state_reg   <= idle;
        rh_reg      <= (others => '0');
        rl_reg      <= (others => '0');
        d_reg       <= (others => '0');
        n_reg       <= (others => '0');
    elsif rising_edge(clk) then
        state_reg   <= state_next;
        rh_reg      <= rh_next;
        rl_reg      <= rl_next;
        d_reg       <= d_next;
        n_reg       <= n_next;
    end if;
end process;

-- FSMD Next-State Logic and Data Path Logic
process(state_reg, n_reg, rh_reg, rl_reg, d_reg, start, dvsr, dvnd, q_bit, rh_temp, n_next)
begin
    ready       <= '0';
    done_tick   <= '0';
    state_next  <= state_reg;
    rh_next     <= rh_reg;
    rl_next     <= rl_reg;
    d_next      <= d_reg;
    n_next      <= n_reg;

    case state_reg is
        when idle =>
            ready <= '1';
            if start = '1' then
                rh_next     <= (others => '0');
                rl_next     <= dvnd;                     -- Dividend
                d_next      <= UNSIGNED(dvsr);           -- Divisor
                n_next      <= TO_UNSIGNED(W+1, CBIT);   -- Index
                state_next  <= op;
            end if;

        when op =>
            --Shift rh and rl left
            rl_next <= rl_reg(W-2 downto 0) & q_bit;
            rh_next <= rh_temp(W-2 downto 0) & rl_reg(W-1);
            --Decrease index
            n_next <= n_reg - 1;
            if(n_next = 1) then
                state_next <= last;
            end if;

        when last =>
            rl_next     <= rl_reg(W-2 downto 0) & q_bit;
            rh_next     <= rh_temp;
            state_next  <= done;

        when done =>
            state_next  <= idle;
            done_tick   <= '1';

    end case;
end process;

-- Compare and Subtract
process(rh_reg, d_reg)
begin
    if rh_reg <= d_reg then
        rh_temp     <= rh_Reg - d_reg;
        q_bit       <= '1';
    else
        rh_temp <= rh_reg;
        q_bit <= '0';
    end if;
end process;

-- Output
quo <= rl_reg;
rmd <= STD_LOGIC_VECTOR(rh_reg);
end Behavioral;

Testbench:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity tb_Divider is
--  Port ( );
end tb_Divider;

architecture Behavioral of tb_Divider is

signal clk, reset, start, ready, done: STD_LOGIC;
signal dvsr, dvnd: STD_LOGIC_VECTOR(7 downto 0);
signal quo, rmd: STD_LOGIC_VECTOR(7 downto 0);

component Divider is
    port(  clk, reset :         in STD_LOGIC;
           start :              in STD_LOGIC;
           dvsr, dvnd :         in STD_LOGIC_VECTOR (7 downto 0);
           ready, done_tick :   out STD_LOGIC;
           quo, rmd :           out STD_LOGIC_VECTOR (7 downto 0));
end component Divider;           

begin

    UUT: Divider port map(  clk => clk, reset => reset, start => start, dvsr => dvsr, dvnd => dvnd, 
                            ready => ready, done_tick => done, quo => quo, rmd => rmd);

    process
    begin
        clk <= '0';
        wait for 10 ns;
        clk <= '1';
        wait for 10 ns;
    end process;

    process
    begin
        start <= '0';
        dvnd <= x"00";
        dvsr <= x"00";
        wait for 100 ns;
        start <= '1';
        dvnd <= x"C8";
        dvsr <= x"0A";
        wait for 10 us;


    end process;

end Behavioral;

Результат тестового стенда: Result of Testbench

...