阅读:2051回复:5
我用vhdl写8254计数器,出现了些问题, 请高手帮忙看看!谢了
library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity chip8254 is port( clk: in std_logic;--时钟 gate: in std_logic;--门信号 wr: in std_logic;--读信号 cs: in std_logic;--片选 cout: buffer std_logic;--输出 data: inout std_logic_vector(7 downto 0)--数据端 ); end chip8254; architecture behave of chip8254 is signal pcr:std_logic_vector(7 downto 0):=\"00000000\";--初值寄存缓冲 signal cr:std_logic_vector(7 downto 0):=\"00000000\";--初值寄存器 signal ce:std_logic_vector(7 downto 0):=\"00000000\";--计数执行单元 signal cnr:std_logic_vector(7 downto 0):=\"00000000\";--控制字寄存器 signal nullcount: std_logic:=\'1\';--是否置入初值 signal stopcount: std_logic:=\'0\';--是否停止计数 begin process(wr)--读数 begin if rising_edge(wr) then--读信号的上升沿 if cnr=0 then--还没有写入控制字 cnr<=data;--写入控制字 case cnr(3 downto 1) is--写入控制字后的cout变化 when \"000\"=>cout<=\'0\'; when \"001\"=>cout<=\'1\'; when \"010\"=>cout<=\'1\'; when \"011\"=>cout<=\'0\'; when \"100\"=>cout<=\'1\'; when \"101\"=>cout<=\'1\'; when others=>null; end case; else--写入初值 pcr<=data; if cnr(3 downto 1)=\"000\" or cnr(3 downto 1)=\"100\" then cr<=pcr;--在方式0和方式4中,初值随时变化 end if; end if; end if; end process; process(gate)--门信号的触发作用 begin if rising_edge(gate) then--上升沿 if cnr(3 downto 1)=\"000\" then--方式0 stopcount<=\'0\';--继续计数 elsif cnr(3 downto 1)=\"001\" then--方式1 if pcr/=cr then--更新初值 cr<=pcr; end if; ce<=cr;--开始计数 nullcount<=\'0\'; cout<=\'0\'; elsif cnr(3 downto 1)=\"010\" then--方式2 if pcr/=cr then--更新初值 cr<=pcr; end if; ce<=cr;--开始计数 nullcount<=\'0\'; elsif cnr(3 downto 1)=\"011\" then--方式3 if pcr/=cr then--更新初值 cr<=pcr; end if; if cr(0)=\'0\' then--初值为偶数 ce<=cr;--初值装入ce else ce<=cr-1;--初值为奇数,初值减一装入ce end if; nullcount<=\'0\';--开始计数 elsif cnr(3 downto 1)=\"100\" then--方式4 ce<=cr;--开始计数 nullcount<=\'0\'; elsif cnr(3 downto 1)=\"101\" then--方式5 if pcr/=cr then--更新初值 cr<=pcr; end if; ce<=cr;--开始计数 nullcount<=\'0\'; else null; end if; end if; end process; process(gate)--门信号触发 begin if falling_edge(gate) then --下降沿 if cnr(3 downto 1)=\"000\" then--方式0 stopcount<=\'1\';--停止计数 elsif cnr(3 downto 1)=\"001\" then--方式1 if pcr/=cr then--更新初值 cr<=pcr; end if; elsif cnr(3 downto 1)=\"010\" then--方式2 if pcr/=cr then--更新初值 cr<=pcr; end if; stopcount<=\'1\';--停止计数 elsif cnr(3 downto 1)=\"011\" then--方式3 if pcr/=cr then--更新初值 cr<=pcr; end if; stopcount<=\'1\';--停止计数 elsif cnr(3 downto 1)=\"100\" then--方式4 stopcount<=\'1\';--停止计数 elsif cnr(3 downto 1)=\"101\" then--方式5 if pcr/=cr then--更新初值 cr<=pcr; end if; else null; end if; end if; end process; process(clk)--时钟 begin if rising_edge(clk) then--时钟上升沿 if cnr(3 downto 1)=\"000\" then--方式0 if cs=\'1\'and gate=\'1\' and stopcount=\'0\'and nullcount=\'0\' then if ce/=0 then--计数未结束 ce<=ce-1; else--计数结束 cout<=\'1\'; nullcount<=\'1\'; end if; end if; elsif cnr(3 downto 1)=\"001\" then--方式1 if cs=\'1\' and nullcount=\'0\' then if ce/=0 then ce<=ce-1; else cout<=\'1\'; nullcount<=\'1\'; end if; end if; elsif cnr(3 downto 1)=\"010\" then--方式2 if cs=\'1\' and nullcount=\'0\' and stopcount=\'0\' and gate=\'1\' then if ce/=0 then--计数未结束 if ce=1 then--计数值为1 cout<=\'0\'; if cr/=pcr then--更新初值 cr<=pcr; end if; else ce<=ce-1; end if; else--计数结束 cout<=\'1\'; ce<=cr;--重新装入初值,开始计数 nullcount<=\'0\'; end if; end if; elsif cnr(3 downto 1)=\"011\" then--方式3 if cs=\'1\' and nullcount=\'0\' and stopcount=\'0\' and gate=\'1\' then if cr(0)=\'0\' then--初值为偶数 if ce/=0 then--计数未结束 ce<=ce-2; else--计数结束 cout<= not cout;--cout反向 if cr/=pcr then--更新初值 cr<=pcr; end if; if cr(0)=\'0\' then--初值为偶数 ce<=cr;--装入初值 else--初值为奇数 ce<=cr-1;--装入初值减一 end if; nullcount<=\'0\';--重新计数 end if; else--初值为奇数 if cout=\'1\' then--cout为高电平 if ce/=-2 then ce<=ce-2; else--计数到-2 if cr/=pcr then--更新初值 cr<=pcr; end if; cout<=\'0\'; ce<=cr-1;--初值减一装入ce nullcount<=\'0\';--重新开始计数 end if; else--cout为低电平 if ce/=0 then ce<=ce-2; else--计数结束 if cr/=pcr then--更新初值 cr<=pcr; end if; cout<=\'1\'; ce<=cr-1;--初值减一装入ce nullcount<=\'0\';--重新开始计数 end if; end if; end if; end if; elsif cnr(3 downto 1)=\"100\" then--方式4 if cs=\'1\' and nullcount=\'0\' and stopcount=\'0\' and gate=\'1\' then if ce/=0 then ce<=ce-1; else--计数结束 cout<=\'0\'; nullcount<=\'1\'; end if; elsif cout=\'0\' and nullcount=\'1\' and ce=0 then--让计数结束后cout值保持一个时钟的低电平 cout<=\'1\'; end if; elsif cnr(3 downto 1)=\"101\" then--方式5 if cs=\'1\' and nullcount=\'0\' then if ce/=0 then ce<=ce-1; else--计数结束 cout<=\'0\'; nullcount<=\'1\'; end if; elsif cout=\'0\' and nullcount=\'1\' and ce=0 then cout<=\'1\';--让计数结束后cout只保持一个时钟的低电平 end if; else null; end if; end if; end process; end behave; ERROR:signal\'cr\' has multiple sources signal\'ce\' has multiple sources signal\'nullcount\'has multiple sources signal\'stopcount\'has multiple sources signal\'count\'has multiple sources |
|
沙发#
发布于:2002-11-28 19:09
library ieee; 在不同的进程中对同一信号赋值了 这是不允许的 |
|
|
板凳#
发布于:2002-11-28 20:52
原代码我没看完,不过这些信号都是同一个错误的。
就是一个信号同时被多个输出驱动,这错误是很明显的,多个输出同时接到一起肯定有问题,你可以用一些数据选择器或三态输出。 可以写成: if 条件1 then OUT <= OUT1; elsif 条件2 then OUT <= OUT2; elsif 条件3 then OUT <= OUT3; 也可用: case is endcase 这两种方式实现,推荐后一种. [编辑 - 11/28/02 by poplar] |
|
|
地板#
发布于:2002-11-28 21:44
但是在不同的PROCESS中不好用上面的方法,在不同PROCESS对同一信号赋值有什么技巧啊
|
|
地下室#
发布于:2002-12-01 01:10
用多路开关啊。
|
|
|
5楼#
发布于:2002-12-07 15:03
process1:process(clk)
data1:=q1; ......... end process; process2:process(clk) data2:=q2; end process; process3:process(temp) if temp=\'1\' then data:=data1; else data:=data2; end if; end process; 加一个控制量就行了 |
|