# Starting a counter by driving a register through UART

Status
Not open for further replies.

#### rahdirs

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:

##### Super Moderator
Staff member
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

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

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

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

##### Super Moderator
Staff member
You don't seem to know how to write a clocked process in VHDL. Maybe you should **broken link removed** 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

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;

##### Super Moderator
Staff member
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.