- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello everyone, I came here in order to find any suggestion for the following issue.
I have a fpga custom board wich needs to make a task depending on the command received by a mcu or pc. For instance, the command <SW> followed by n bytes of data will change the frequency of a DDS system, and so on with other 4 bytes commands (4 ASCII chars). I already have my UART component workin and tested with the windows hyperterminal wich echos back every key pressed. I tried with a 8bit shift left register and a counter in order to "concatenate" the command and later compare it in order to perform the correspondig action, but I just can't make it work. Does anyone already did something like that before? the pseudo code is the following
...
architecture arch of myEntity is
signal RxReady : std_logic;
signal enableTx : std_logic;
signal cmd : std_logic_vector(31 downto 0) := (others => '0');
signal cmd_tmp : std_logic_vector(31 downto 0) := (others => '0');
signal tmp_data : std_logic_vector(7 downto 0) := (others => '0');
signal cont : integer range 0 to 4 := 0;
begin
u1 : UART port map (sysclk, sysrst, enableTx, TxD, TxData, RxD, tmp_data, RxReady);
process(sysrst, tmp_data, RxReady)
begin
if sysrst = '1' then
enableTx <= '0';
cmd <= (others => '0');
cmd_tmp <= (others => '0');
else
if RxReady = '1' then
if cont < 4 then
cont := cont + 1;
cmd_tmp <= cmd_tmp(23 downto 0) & tmd_data;
cmd <= cmd_tmp;
else
cont := 0;
end if;
else
end if;
end if;
end process;
process(cmd)
begin
-- just a Test, but not working, it only has the last char coming from the PC, i.e, a sequence 1234, should be 1234, but it is just 4444
if cmd = one&two&three&four then
outLEDS <= (others => '1');
else
outLEDS <= (others => '0');
end if;
end process;
end architecture;
...
If anyone have a suggestion it will be really appreciated. Thanks in advance.
Link Copied
2 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
just my two cents... You have a mix-up of variable assignment (cont := cont+1) which takes place immediately and signal assignments " <= " which take place "once" the condition is met. Additionally you should synchronize the process for concatenating the command to sysclk rather using the outputflag of the UART process for stringent clock synchronous design... Additionally the cont variable increases to 4 (being pure combinatorical, not registered) with the RxReady being '1', not with the rising edge of RxReady indicating a new command being received. It may already solve the issue, if you define cont as a signal as well and rewrite the condition from "If RxReady = '1' " to "If Rising_Edge(RxReady)" to envoke these code lines only once for each time you get a new byte by the UART... Regards, Carlhermann- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Carlhermann,
First of all I want to thank you for your comments and suggestions :o. I was able to solve this issue, part of it was make changes like you suggested before. --- Quote Start --- ...Additionally you should synchronize the process for concatenating the command to sysclk rather using the outputflag of the UART process for stringent clock synchronous design... --- Quote End --- Also I built a FSM for handling the "commands", the code I sure could be improved a lot in order to be more "compact" or efficient; but at least it is working now. Here's the code
...
-- Commands FSM
process(sysrst, sysclk, txEnable, rxData)
begin
if sysrst = '0' then
txEnable <= '0';
txData <= (others => '0');
cmd_ctr <= 0;
cmd_state <= IDLE;
commands <= (others => '0');
elsif sysclk'event and sysclk = '1' then
case cmd_state is
when IDLE =>
txEnable <= '0';
txData <= (others => '0');
if rxReady = '1' then
cmd_state <= START_CMD;
else
cmd_state <= IDLE;
cmd_rdy <= '0';
cmd_ctr <= 0;
commands <= (others => '0');
end if;
when START_CMD =>
case cmd_ctr is
when 0 =>
commands <= commands(23 downto 0) & rxData;
cmd_ctr <= 1;
cmd_state <= START_CMD;
when 1 =>
if rxReady = '1' then
commands <= commands(23 downto 0) & rxData;
cmd_ctr <= 2;
cmd_state <= START_CMD;
end if;
when 2 =>
if rxReady = '1' then
commands <= commands(23 downto 0) & rxData;
cmd_ctr <= 3;
cmd_state <= START_CMD;
end if;
when 3 =>
if rxReady = '1' then
commands <= commands(23 downto 0) & rxData;
cmd_ctr <= 0;
cmd_state <= WHICH_CMD;
end if;
end case;
when WHICH_CMD =>
...
Thanks again for your support. Regards, Efel
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page