Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Starting a counter by driving a register through UART

Status
Not open for further replies.

rahdirs

Advanced Member level 1
Joined
May 22, 2013
Messages
424
Helped
93
Reputation
192
Reaction score
91
Trophy points
1,308
Location
Mordor
Activity points
4,496
Hi,

The subject title of this question came out a bit weird,so i'm going to explain my query -

From UART i'm driving a 32 bit register(write_high).The register is the number of clock cycles i want to keep wr_en of FIFO high.
So if that register was x"0000000F" - then wr_en needs to be high for 15 clk cycles.

I was thinking of writing something simple like :

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
signal count   : std_logic_vector(31 downto 0) := x"00000000";
--
--write high is the register into which UART will write number of pulses to store
begin
 
process(clk)
if (write_high /= x"00000000") then
       fifo_wr_en <= '1';
    if (count = write_high) then
       fifo_wr_en  <= '0';
    -- count <= x"00000000"
    else
       count        <= count + '1';
    end if;
else
   fifo_wr_en  <= '0';
end if;
end process;



But the above snippet will not do as the count can't be brought back to 0 after counting for write_high number of cycles as it will again keep counting for those cycles if we bring it to 0.
 
Last edited:

ads-ee

Super Moderator
Staff member
Joined
Sep 10, 2013
Messages
7,820
Helped
1,811
Reputation
3,632
Reaction score
1,772
Trophy points
1,393
Location
USA
Activity points
59,033
Then go the other direction and load the count with the write_high value and decrement if the count is not equal to 0. You only load the write_high value anytime the UART register is written so it won't restart unless you do another UART write. If you make the write_high UART regisiter the counter then you don't even need to detect the UART write to the register, once it's not 0 it starts decrementing.

In your code what you are missing is a signal that tells you when the UART updates the write_high value, that is what would reset the counter.
 

dpaul

Advanced Member level 4
Joined
Jan 16, 2008
Messages
1,480
Helped
307
Reputation
614
Reaction score
303
Trophy points
1,373
Location
Germany
Activity points
11,082
So what I understand is that if only there is a new value written to write_high[32] then only the counter needs to be reset and wr_en should go from high to low.
If so then then use a flag_bit which would always be updated per clock cycle. If there is new value on write_high , then only the flag_bit has to be set, else if the old reg. remains the keep it reset. Depending on this you can reset you count, so that wr_en does not go high again.
One more point, please review the signals listed in your sensitivity list.
 

rahdirs

Advanced Member level 1
Joined
May 22, 2013
Messages
424
Helped
93
Reputation
192
Reaction score
91
Trophy points
1,308
Location
Mordor
Activity points
4,496
If you make the write_high UART regisiter the counter then you don't even need to detect the UART write to the register, once it's not 0 it starts decrementing.

In your code what you are missing is a signal that tells you when the UART updates the write_high value, that is what would reset the counter.


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
signal count   : std_logic_vector(31 downto 0) := x"00000000";
--
--write high is the register into which UART will write number of pulses to store
begin
 
process(clk,write_high,uart_wr_en,uart_addr,count)
if (write_high /= x"00000000") then
       fifo_wr_en <= '1';
    if (count = write_high) then
       fifo_wr_en  <= '0';
    elsif (uart_wr_en = '1' and uart_addr = x"0005") then
       count         <= x"00000000";
    else
       count        <= count + '1';
    end if;
else
   fifo_wr_en  <= '0';
end if;
end process;


I guess this is what you are suggesting in your last line.uart_wr_en is high when you are writing into uart & uart_addr is also included because i have a lot of uart registers.

In the last before line where you were saying,you can also make write_high as a counter & decrement it.In that case we are driving write_high register through two different processes.one processes is uart & other is the process which i'm doing now
 

ads-ee

Super Moderator
Staff member
Joined
Sep 10, 2013
Messages
7,820
Helped
1,811
Reputation
3,632
Reaction score
1,772
Trophy points
1,393
Location
USA
Activity points
59,033
You don't seem to know how to write a clocked process in VHDL. Maybe you should review your VHDL before trying to design this circuit.

As you've had problems with your designs before, did you take the recommendations of myself and others and draw a schematic of the design before coding in VHDL? Until you are comfortable with translating between schematic circuits and their VHDL descriptions, without having to think about doing it, you shouldn't skip this step before writing VHDL.

If I understand what you are trying to accomplish I would probably write this as:
Code:
fifo_we <= '0';
if (uart_wr_en = '1' and uart_addr = x"0005") then
  count <= (others => '0');
elsif (count < write_high) then
  count <= count + 1;
  fifo_we <= '1';
end if;
 

rahdirs

Advanced Member level 1
Joined
May 22, 2013
Messages
424
Helped
93
Reputation
192
Reaction score
91
Trophy points
1,308
Location
Mordor
Activity points
4,496
If I understand what you are trying to accomplish I would probably write this as:
Code:
fifo_we <= '0';
if (uart_wr_en = '1' and uart_addr = x"0005") then
  count <= (others => '0');
elsif (count < write_high) then
  count <= count + 1;
  fifo_we <= '1';
end if;

Those syntax errors were only because i was directly writing the code here on website rather than in a suitable text editor.
But i don't see much difference between what these two codes accomplish except me not following syntax & then including a rising_edge statement for clk
Code:
if (write_high /= x"00000000") then
       fifo_wr_en <= '1';
    if (count = write_high) then
       fifo_wr_en  <= '0';
    elsif (uart_wr_en = '1' and uart_addr = x"0005") then
       count         <= x"00000000";
    else
       count        <= count + '1';
    end if;
else
   fifo_wr_en  <= '0';
end if;
 

ads-ee

Super Moderator
Staff member
Joined
Sep 10, 2013
Messages
7,820
Helped
1,811
Reputation
3,632
Reaction score
1,772
Trophy points
1,393
Location
USA
Activity points
59,033
But i don't see much difference between what these two codes accomplish except me not following syntax & then including a rising_edge statement for clk

How about, because your code doesn't work as you've defined the requirements. Your code will continue to write for eternity until you make write_high = 0.

That is the problem with writing convoluted (not distilled down to the fundamental behavior needed) code with nested if's inside of other if statements. Writing concise code is both easier to read and to understand. It's also easier to avoid bugs like the one you have in your version.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top