0

这是一个长除法二进制除法器的模拟。该程序按预期执行,但无论我如何编码,它都不会从寄存器的 5 个 MSB 中减去除数。

以下是代码:

            library ieee;
            use ieee.std_logic_1164.all;
            use ieee.std_logic_unsigned.all;
            use ieee.std_logic_arith.all;

            ENTITY divider IS

                PORT(
                            Clock               :IN STD_LOGIC;
                            Dividend            :IN STD_LOGIC_VECTOR(7 DOWNTO 0);
                            Divisor         :IN STD_LOGIC_VECTOR(4 DOWNTO 0);
                            Reset               :IN STD_LOGIC;
                            St                  :IN STD_LOGIC;

                            outDRegister            :OUT STD_LOGIC_VECTOR(8 DOWNTO 0):="000000000";
                            outCurrentState         :OUT STD_LOGIC_VECTOR(2 DOWNTO 0):="000";
                            Quotient            :OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
                            Remainder       :OUT STD_LOGIC_VECTOR(4 DOWNTO 0));
            END divider;

            ARCHITECTURE Behavior of divider IS

            SIGNAL DRegister                        :STD_LOGIC_VECTOR(8 DOWNTO 0);
            SIGNAL SubOut                           :STD_LOGIC_VECTOR(4 DOWNTO 0);
            Signal C,ShiftIn, ShiftRes          :STD_LOGIC;
            Signal ShiftEnable                  :STD_LOGIC;
            Signal tempSt                           :STD_LOGIC:='1';
            TYPE    State_type IS (S0, S1, S2, S3, S4, S5);
            SIGNAL y:State_type:=S0;

            BEGIN
            PROCESS(Dividend,Divisor,y, st, reset, clock) IS
            BEGIN
            If (Reset='0') THEN
            Y<=S0;
            ELSIF (Clock'EVENT and CLOCK = '1') THEN

                CASE y IS
                    WHEN S0=>
                        IF(st='0' AND tempSt='1' AND reset = '1') THEN
                            DRegister <= '0'&Dividend;
                            y<=S1;
                        ELSIF(st='1' AND reset = '1') THEN
                            Quotient    <= DRegister(3 DOWNTO 0);
                            Remainder   <= DRegister(8 DOWNTO 4);
                            y<=S0;
                        END IF;
                        outDRegister<=DRegister;
                        outCurrentState<="000";
                        tempSt<=st; 

                    WHEN S1=>
                        IF(DRegister(8 DOWNTO 4)>=Divisor) THEN
                            y<=S0;
                        ELSE
                            DRegister <= (DRegister(7 DOWNTO 0) & '0');
                            y<=S2;
                        END IF;
                        outDRegister<=DRegister;
                        outCurrentState<="001";
                    WHEN S2=>
                        IF(DRegister(8 DOWNTO 4)>=Divisor) THEN
                            DRegister(8 DOWNTO 4)<=(DRegister(8 DOWNTO 4) - Divisor);--Does not work!! Does nothing.
                            DRegister <= DRegister(7 DOWNTO 0) & '1';
                        ELSE
                            DRegister <= DRegister(7 DOWNTO 0) & '0';
                        END IF;
                        outDRegister<=DRegister;
                        outCurrentState<="010";     
                        y<=S3;

                    WHEN S3=>
                        IF(DRegister(8 DOWNTO 4)>=Divisor) THEN
                            DRegister(8 DOWNTO 4)<=(DRegister(8 DOWNTO 4) - Divisor);--Does not work!! Does nothing.
                            DRegister <= DRegister(7 DOWNTO 0) & '1';
                        ELSE
                            DRegister <= DRegister(7 DOWNTO 0) & '0';

                        END IF;
                        outDRegister<=DRegister;
                        outCurrentState<="011";
                        y<=S4;

                    WHEN S4=>
                        IF(DRegister(8 DOWNTO 4)>=Divisor) THEN
                            DRegister(8 DOWNTO 4)<=(DRegister(8 DOWNTO 4) - Divisor);--Does not work!! Does nothing.
                            DRegister <= DRegister(7 DOWNTO 0) & '1';
                        ELSE
                            DRegister <= DRegister(7 DOWNTO 0) & '0';
                        END IF;
                        outDRegister<=DRegister;
                        outCurrentState<="100";
                        y<=S5;

                    WHEN S5=>   
                        IF(DRegister(8 DOWNTO 4)>=Divisor) THEN
                            DRegister(8 DOWNTO 4)<=(DRegister(8 DOWNTO 4) - Divisor);--Does not work!! Does nothing.
                        END IF;
                        outDRegister<=DRegister;
                        outCurrentState<="101";

                        y<=S0;

                END CASE;

            END IF;




            END PROCESS;


            END Behavior;
4

2 回答 2

0

第一步是阅读 VHDL 中变量和信号分配之间的差异。你的问题就在那里。一种解决方案涉及问题状态的中间变量;另一个涉及重写信号分配。

我通常的解释是在这里,页面底部有一个链接到“VHDL's Crown Jewel”,这也非常值得一读。

另请注意:

  • 有更好的算术库:ieee.numeric_std 而不是 std_logic_unsigned 或 std_logic_arith 或(最糟糕的是)将两者混合。
  • 算术有比 std_logic_vector 更好的数据类型:ieee.numeric_std.unsigned(或有符号),甚至是integeror的子类型natural
  • 当您正在编写一个干净的单进程状态机时,它的敏感度列表只需要clock, reset
  • 您可以在条件表达式周围丢失括号,If Reset='0' Then这很好(这不是您父亲的 C 编译器)
  • rising_edge(Clock)是首选,Clock'EVENT and CLOCK = '1'
    但这些都是主要问题的外围。
于 2013-11-21T10:49:04.517 回答
0

正如您还标记的那样,有问题的代码部分是:

...
DRegister(8 downto 4) <= (DRegister(8 downto 4) - Divisor);  --Does not work!! Does nothing.
DRegister             <= DRegister(7 downto 0) & '1';
...

在 VHDL 中,信号的值在当前仿真周期结束之前不会更新,因此上面DRegister第二次赋值中使用 的值DRegister不会被第一次赋值改变DRegister

因此,第一个分配给的效果DRegister(8 downto 4)被第二个分配给 中的所有位所覆盖DRegister,因此减去 Divisor没有任何效果。

一种纠正代码的方法,因此只对所有DRegister位进行一次分配。

您可能想在 https://stackoverflow.com/a/20104800/2352082上查看 David Koontz 的回答,因为这涵盖了类似的问题。

于 2013-11-21T10:55:24.717 回答