我是vhdl的初学者,我正在尝试使用shift和subtract方法制作一个8位分频器。分配器的代码是可以的,我猜,但我在模拟输入时遇到问题。当我使用verilog测试夹具时,我的输入应该是(dividend = 51 [00110011b],divisor = 19 [00010011b])总是在iSim中变为(dividend = 49 [00110001b],divisor = 49 [00110001b])) ,然后输出(商和余数= xxxxxxx(未知))而不是(商= 2 [00000010b]和余数= 13 [00001101b])... 正如我之前提到的,我是vhdl的初学者,我已经在这里工作了五个小时,我已经尽力在网上搜索解决方案但是失败了....所以任何帮助或替代解决方案都将不胜感激。 我正在使用Xilinx ISE 14.3和iSim。
这是8位二进制分频器的代码。
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use IEEE.STD_LOGIC_ARITH.all;
entity division is
generic(SIZE: INTEGER := 8);
port(reset: in STD_LOGIC; --reset
en: in STD_LOGIC; --enable
clk: in STD_LOGIC; --clock
num: in STD_LOGIC_VECTOR((SIZE - 1) downto 0); --dividend
den: in STD_LOGIC_VECTOR((SIZE - 1) downto 0); --divisor
res: out STD_LOGIC_VECTOR((SIZE - 1) downto 0); --result/quotient
rm: out STD_LOGIC_VECTOR((SIZE - 1) downto 0) --remainder
);
end division;
architecture behav of division is
signal bufreg: STD_LOGIC_VECTOR((2 * SIZE - 1) downto 0); --signal array to hold both accumulator and dividend registers as one i.e bufreg(18 bits)
signal dbuf: STD_LOGIC_VECTOR((SIZE - 1) downto 0); --signal array to hold the divisor
signal count: INTEGER range 0 to SIZE; --count to determine when to stop
alias ADreg is bufreg((2 * SIZE - 1) downto SIZE); --ADreg is is alias for top half of bufreg register(17th to 9th bit)
alias DVNDreg is bufreg((SIZE - 1) downto 0); --DVNDreg is is alias for bottom half of bufreg register(8th to 0th bit)
begin
--our process begins here
p_001: process(reset, en, clk)
begin
if reset = '1' then
res <= (others => '0');
rm <= (others => '0');
count <= 0;
elsif rising_edge(clk) then
if en = '1' then
case count is
when 0 =>
ADreg <= (others => '0');
DVNDreg <= num;
dbuf <= den;
res <= DVNDreg;
rm <= ADreg;
count <= count + 1;
when others =>
if bufreg((2 * SIZE - 2) downto (SIZE - 1)) >= dbuf then
ADreg <= '0' & (bufreg((2 * SIZE - 3) downto (SIZE - 1)) - dbuf((SIZE - 2) downto 0));
DVNDreg <= DVNDreg ((SIZE - 2) downto 0) & '1';
else
bufreg <= bufreg((2 * SIZE - 2) downto 0) & '0';
end if;
if count /= SIZE then
count <= count + 1;
else
count <= 0;
end if;
end case;
end if;
end if;
end process;
end behav;
以下是Verilog测试夹具(.v文件)的代码:
module BINdivisionTEST;
// Inputs
reg reset;
reg en;
reg clk;
reg [7:0] num ;
reg [7:0] den ;
// Outputs
wire [7:0] res;
wire [7:0] rm;
// Instantiate the Unit Under Test (UUT)
division uut (
.reset(reset),
.en(en),
.clk(clk),
.num(num),
.den(den),
.res(res),
.rm(rm)
);
initial begin
// Initialize Inputs
reset = 0;
en = 0;
clk = 0;
//num = 0;
//den = 0;
// Wait 100 ns for global reset to finish
#100;
en = 1;
#100;
clk=1;
num <= "00110011" ;
den <= "00010011" ;
// Add stimulus here
end
endmodule
我最大的问题似乎是输入的初始化,可能是一些错误的分配,误用测试夹具文件和一些错误的编码。 我还应该补充说,分隔符代码是在vhdl,ISE 14.3中编译的。 我非常抱歉,如果之前已经回答了这个问题,我不是故意通过上传不良和业余代码来惹恼任何人。如果此类问题已经解决,请您提供链接。 再次,非常感谢任何帮助。
答案 0 :(得分:2)
模拟器可能会将它们视为字符串而不是数字。尝试更改:
num <= "00110011" ;
den <= "00010011" ;
为:
num <= 8'b00110011;
den <= 8'b00010011;
答案 1 :(得分:1)
我不是Verilog的专家,但看起来你可能没有在测试之前断言重置为你的VHDL组件。
这会使“Count”处于未初始化状态,这样当你使用它时,任何事情都可能发生,而“XXXX”输出则反映了这一点。
重置序列应该类似于
En <= '0';
Clk <= '0';
Reset <= '1';
wait for 100 ns;
Reset <= '0';
wait for 100 ns;
-- start testing here
(当然是VHDL ......但它很容易转换为Verilog)