输出在分频器代码VHDL中始终为零(商和余数)

时间:2015-02-15 10:51:35

标签: vhdl

下面显示的代码中的输出始终为零(商和余数)。 即使我将b的值赋给余数,也给出了0.我已经多次检查但是我无法理解问题是什么。在编译时,它显示2个警告:

- Initial value of "b" depends on value of signal "divisor".

有什么问题?

- DIVIDER

library ieee;  
use ieee.numeric_bit.all;  

entity unsigned_divider is  
port(
-- the two inputs  
dividend: in bit_vector(15 downto 0);  
divisor : in bit_vector(15 downto 0);  
-- the two outputs  
quotient : out bit_vector(15 downto 0);  
remainder : out bit_vector(15 downto 0)  
);  
end entity unsigned_divider;  

architecture behave of unsigned_divider is  

begin  
process  

variable a : bit_vector(15 downto 0):=dividend;  
variable b : bit_vector(15 downto 0):=divisor;  

variable p : bit_vector(15 downto 0):= (others => '0');  
variable i : integer:=0;  
begin  

for i in 0 to 15 loop  
p(15 downto 1) := p(14 downto 0);  
p(0) := a(15);  
a(15 downto 1) := a(14 downto 0);  
p := bit_vector(unsigned(p) -  unsigned(b));  

if(p(15) ='1') then  
a(0) :='0';  
p := bit_vector(unsigned(p) +  unsigned(b));  
else  
a(0) :='1';  
end if;  
wait for 1 ns;  

end loop;

quotient <= a after 1 ns;  
remainder <= p  after 1 ns;  

end process;
end behave;

2 个答案:

答案 0 :(得分:0)

变量分配立即生效;但是在创建该变量时,信号没有任何价值,所以你不能指望分配

variable a : bit_vector(15 downto 0):=dividend;  
variable b : bit_vector(15 downto 0):=divisor;

正常工作。我有点惊讶的是,对变量a的赋值没有抱怨。也许这是你的第二个警告。您应该按照自己的方式定义变量,但请稍后将该分配保留在流程的begin段中。

P.S。此外,您可能希望将remainder <= p after 1ns;更改为remainder <= p after 1 ns;

答案 1 :(得分:0)

您应该对流程语句部分中的变量a和b进行明确赋值(作为顺序信号赋值)。声明:

        variable a : bit_vector(15 downto 0):=dividend;  
        variable b : bit_vector(15 downto 0):=divisor;  

应该是:

        variable a : bit_vector(15 downto 0);  
        variable b : bit_vector(15 downto 0);  

在流程声明部分(在流程开始之后):

        a := dividend;
        b := divisor;

这些克服了natipar提到的问题,即在初始化期间仅将值分配给a和b。

如果您希望延迟1 ns,则应该有一个显式的wait语句作为process语句进程语句部分的最后一个顺序语句:

wait on dividend, divisor;

这些使您的流程语句看起来像这样(添加了缩进):

    process  

        variable a : bit_vector(15 downto 0); -- := dividend;  
        variable b : bit_vector(15 downto 0); -- := divisor;  

        variable p : bit_vector(15 downto 0) :=  (others => '0');  
        variable i : integer := 0;  
    begin  

        a := dividend;
        b := divisor;

        for i in 0 to 15 loop  
            p(15 downto 1) := p(14 downto 0);  
            p(0) := a(15);  
            a(15 downto 1) := a(14 downto 0);  
            p := bit_vector(unsigned(p) -  unsigned(b));  

            if  p(15)  = '1'  then  
                a(0) :='0';  
                p := bit_vector(unsigned(p) +  unsigned(b));  
            else  
                a(0) := '1';
            end if;  
            wait for 1 ns;  

        end loop;

        quotient <= a after 1 ns;  
        remainder <= p  after 1 ns;  

        wait on dividend, divisor;

    end process;

(注意数字文字和单位之间的空格,IEEE Std 1076-2008要求,15.3词汇要素,分隔符和分隔符第4段,最后一句&#34;标识符之间至少需要一个分隔符或一个抽象的文字和一个相邻的标识符或抽象的文字。&#34;,尽管Modelsim不要求它。)

编写一个简单的测试平台,我们在恢复分区算法中发现至少一个错误:

entity unsigned_divider_tb is
end entity;

architecture foo of unsigned_divider_tb is
    signal dividend, divisor: bit_vector (15 downto 0) := (others => '0');
    signal quotient, remainder: bit_vector (15 downto 0);

    function to_string(inp: bit_vector) return string is
        variable image_str: string (1 to inp'length);
        alias input_str:  bit_vector (1 to inp'length) is inp;
    begin
        for i in input_str'range loop
            image_str(i) := character'VALUE(BIT'IMAGE(input_str(i)));
        end loop;
        return image_str;
    end;

begin
DUT:
    entity work.unsigned_divider
        port map (
            dividend,
            divisor,
            quotient,
            remainder
        );
MONITOR:
    process (quotient, remainder)
    begin
        report "quotient = " & to_string (quotient) severity NOTE;
        report "remainder = " & to_string (remainder) severity NOTE;
    end process;

end architecture;
  

ghdl -a unsigned_divider.vhdl
  ghdl -e unsigned_divider_tb
  ghdl -r unsigned_divider_tb
  unsigned_divider.vhdl:83:9:@ 0ms :(报告单):商= 0000000000000000
  unsigned_divider.vhdl:84:9:@ 0ms :(报告说明):余数= 0000000000000000
  unsigned_divider.vhdl:83:9:@ 17ns :(报告单):商= 1111111111111111
  unsigned_divider.vhdl:84:9:@ 17ns :(报告说明):余数= 0000000000000000

(关于解释的说明,在0毫秒时报告的交易是由于详细说明而执行的默认分配。)

你的算法给出了除以0的错误答案。

向测试平台添加刺激过程:

STIMULUS:
    process
    begin
        wait for 20 ns;
        dividend <= x"ffff";
        divisor <= x"000f";
    end process;

显示它也可以得到正确答案:

  

unsigned_divider.vhdl:83:9:@ 37ns :(报告单):quotient = 0001000100010001
  unsigned_divider.vhdl:84:9:@ 37ns :(报告说明):余数= 0000000000000000

使用测试平台并在刺激过程中添加等待声明和作业,您可以进一步探索。

我自己一直都是非恢复部门的粉丝,因为增加或减少会在时钟分频器中占用一个时钟。