高手们帮忙看下我写的VHDL,大概知道是什么错误,但不清楚怎么改。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity cabu is
generic(width:integer:=5);
port(
data:in std_logic_vector(width-1 downto 0);
lctl:in std_logic_vector(3 downto 0);
lclk:in std_logic;
rctl:in std_logic;
wdir:in std_logic;
ndir:in std_logic;
clk: in std_logic;
pulseut std_logic;
finish:inout std_logic;
eacc:in std_logic
--precntut std_logic_vector(width-1 downto 0)
);
end cabu;
architecture behave of cabu is
signal postcnt,cnt,curcnt,precnt:std_logic_vector(width-1 downto 0);
signal postv,velcnt,curv,minv,prev:std_logic_vector(width-1 downto 0);
signal accelerate,avcnt:std_logic_vector(width-1 downto 0);
signal accbool:std_logic;
signal rdir:std_logic;
begin
load:process(lclk)
begin
if(lclk'event and lclk='1') then
case lctl is
when "0000" =>
postcnt<=data;
when "0001" =>
cnt<=data;
when "0010" =>
curcnt<=data;
when "0011" =>
precnt<=data;
when "0100" =>
postv<=data;
when "0101" =>
velcnt<=data;
when "0110" =>
curv<=data;
when "0111" =>
minv<=data;
when "1000" =>
prev<=data;
when "1001" =>
accbool<=data(0);
when "1010" =>
accelerate<=data;
when others =>
end case;
end if;
end process;
rdir<=wdir xor ndir;
run:process(clk)
begin
if(clk'event and clk='1') then
case rctl is
when '0'=>--运行
if rdir='0' then--正转
if velcnt=2 then
pulse<='1';
velcnt<=velcnt-1;
cnt<=cnt-1;
elsif velcnt=1 then
pulse<='0';
if cnt=1 then
finish<='1';--这一小段插补结束;
precnt<=curcnt;
cnt<=postcnt;
curcnt<=postcnt;
prev<=curv;
velcnt<=postv;
curv<=postv;
else
end if;
elsif velcnt=0 then
pulse<='0';
velcnt<="00000";
else
velcnt<=velcnt-1;
pulse<='0';
end if;
elsif rdir='1' then--反转
end if;
when '1'=>--停止
end case;
end if;
end process;
end behave;
Some dicuess of your program
Forgive me, I can not type Chinese.
Your Problem is Share the Same signal at the same time , that because you use different Clock,
Load Process uses “lclk” ,and the Run Process used the “clk”.
We can consider the situation is that ,Just after Process Run modify the Value of one Signal, the Load Process convert the real Value, That will cause “classic Share Data Problem”
About Solution,
I want to know what is your really aim to accomplished in this program, Why you want to have 2 clocks, and the 2 process are separately or Happened by sequential.
En, Now I can give you a solution which I assume the two Process happen by the sequence of Load first and Run,
Just a Hint (Testing by Xilinx ISE 8.2 )
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity cabu is
generic(width:integer:=5);
port(
data:in std_logic_vector(width-1 downto 0);
lctl:in std_logic_vector(3 downto 0);
lclk:in std_logic;--load clk
rctl:in std_logic;
wdir:in std_logic;
ndir:in std_logic;
clk: in std_logic;
pulseut ut std_logic;
finish:inout std_logic;
eacc:in std_logic
--precntut std_logic_vector(width-1 downto 0)
);
end cabu;
architecture behave of cabu is
signal postcnt,cnt,curcnt,precnt:std_logic_vector(width-1 downto 0);
signal postv,velcnt,curv,minv,prev:std_logic_vector(width-1 downto 0);
signal accelerate,avcnt:std_logic_vector(width-1 downto 0);
signal accbool:std_logic;
signal rdir:std_logic;
signal pulse :std_logic;
Type Ope_state_Type is (T0,T1,T2);--define the operation state
signal Ope_state : Ope_state_Type;
signal Next_Ope_state : Ope_state_Type ;
begin
load:process(clk)
begin
case Ope_state is
when T0 =>--do Load operation
case lctl is
when "0000" =>
postcnt<=data;
when "0001" =>
cnt<=data;
when "0010" =>
curcnt<=data;
when "0011" =>
precnt<=data;
when "0100" =>
postv<=data;
when "0101" =>
velcnt<=data;
when "0110" =>
curv<=data;
when "0111" =>
minv<=data;
when "1000" =>
prev<=data;
when "1001" =>
accbool<=data(0);
when "1010" =>
accelerate<=data;
when others =>
end case;
Next_Ope_State <= T1;
when T1 =>
case rctl is
when '0'=>
if rdir='0' then
if velcnt="0010" then
pulse<='1';
velcnt<= velcnt-'1';-- need to do logic operation
cnt<=cnt-'1';
elsif velcnt="0001" then
pulse<='0';
if cnt=1 then
finish<='1';
precnt <=curcnt;
cnt <=postcnt;
curcnt <=postcnt;
prev<=curv;
velcnt<=postv;
curv<=postv;
else
end if;
elsif velcnt="0000" then
pulse<='0';
velcnt<="00000";
else
velcnt<=velcnt-'1';
pulse<='0';
end if;
elsif rdir='1' then
end if;
when '1'=>
when others =>---consider the situation is that, the std_logic not just has the '1' and '0' also has the V ,X
end case;
next_Ope_state <= T0;
when others =>
end case;-- end the case Ope_state
end process;
rdir<=wdir xor ndir;
clock_event : process( clk )
begin
if (clk'event and clk = '1') then
Ope_state<= Next_Ope_state;
end if;
end process;
end behave;
回复 #2 lemony.vhdl 的帖子
Thank you for your help.
The aim of my program is something like this: A counter and a
register,the register can be translated data when the counter is
counting,the counter subtract 1 when come a run clk,when it is 0,
the register give data to it.
So,the main character of my program is the counter count without
halt.I must revolse how to translate data to register when counter is
counting.The lclk is not a clk,but like a enable port, active when want
to load data to register.
thank you again,forgive me for my poor English.