大家都在聊电源,聊技术,今天我想和大家探讨一下“个人习惯”。
晶振频率为50M,经过50M分频后,理论上应该输出1HZ的,可实际输出的有4HZ左右(粗略估计),而用50K*1K分频后结果却是1HZ,想来想去,这50K*1K应该是50M,什么原因呢?你猜,什么原因?
提出假设:
软件不支持这么大的数?24999999。
硬件不支持这么大的数?那这芯片岂不弱爆了。
晶振误差?都差4倍了还叫误差,这种错误在伊拉克战场上就该枪毙5分钟了。
RP问题?这个绝对没有问题!
后来经多方会诊,诊断结果如下:(对关键部位进行了注释,如果对VHDL语言不了解,请直接无视代码)
ARCHITECTURE ONE OF CLKDIV IS
SIGNAL COUNT:STD_LOGIC_VECTOR(22 DOWNTO 0);
--设置一个位宽为23的信号 COUNT
SIGNAL CLK_DIV_TEMP:STD_LOGIC;
BEGIN
PROCESS(CLK)
BEGIN
IF(CLK'EVENT AND CLK='1')
THEN
IF(COUNT= 24999999)
--count计数到24999999后CLK_DIV_TEMP反转一次,计数50000000后是一个周期
THEN
COUNT<=(OTHERS =>'0');
CLK_DIV_TEMP<=NOT CLK_DIV_TEMP;
ELSE
COUNT <= COUNT + 1;
END IF;
END IF;
END PROCESS;
CLK_DIV<=CLK_DIV_TEMP;
END ONE;
解决问题:
下面通过一系列的计算来说明问题
2^23=8388608,
24999999转换为二进制是1011111010111100000111111,位宽为25,
2^25=33554432,
也就是说count最大只能加到8388608,而不是所想要的24999999,
这一句SIGNAL COUNT:STD_LOGIC_VECTOR(22 DOWNTO 0);
要改成SIGNAL COUNT:STD_LOGIC_VECTOR(24 DOWNTO 0);
之后就正常了
想想开始做的时候没有计算,觉得23的位宽已经够大了,事实证明,万事要脚踏实地啊,否则会经常吃“差不多了”的亏。
|