这是一个长除二进制分频器的模拟。该程序按预期执行,但不管我如何编码它都不会从寄存器的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;
答案 0 :(得分:0)
第一步是阅读VHDL中变量和信号分配之间的差异。你的问题就在那里。一种解决方案涉及问题状态的中间变量;另一个涉及重写信号分配。
我通常的解释是here,页面底部有一个链接到“VHDL的Crown Jewel”,这也非常值得一读。
另请注意:
integer
或natural
的子类型; clock, reset
If Reset='0' Then
很好(这不是您父亲的C编译器)rising_edge(Clock)
优先于Clock'EVENT and CLOCK = '1'
答案 1 :(得分: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
中的所有位,从而减去。{1}}
Divisor
没有任何效果。
纠正代码的一种方法,所以只对一个DRegister
位进行一次分配。
你可能想看看David Koontz的回答 https://stackoverflow.com/a/20104800/2352082因为这涉及类似的问题。