Xilinx vhdl counter recognised as register

  • Thread starter Sanka Piyaratna
  • Start date
S

Sanka Piyaratna

Hi,

I have a peice of VHDL code that has a counter implemented as shown below:

signal rx_frame_counter : unsigned(REGISTER_SIZE - 1 downto 0);

frame_counter <= frame_counter + 1;
if frame_counter >= registered_error_freq then
----
end if;

Post synthesis report from ISE 8.1 (xst), tells me that it recognised
frame_counter as a register. Shouldn't frame_counter be recognised as a
counter to be the optimum design. My question is why this is happening
and also is there any way to tell the xst to recognise this as a counter.

Thank you,

Sanka
 
L

lundril

Sorry, but if you don't post the code you actually use, how can anyone
tell
what you are actually doing ?

I assume that your

frame_counter <= frame_counter + 1;

statement is in a process (otherwise it doesn't make sense) ?
How is it implemented exactly ? (Any resets , enable signals ... ?)

so long
lundril
 
S

Sanka Piyaratna

My appologies.

This code is implemented in a process and this particular process is
very large, but the process where the counter is implemented as follows.

Sanka

p_main_sm : process (rxclk_i, rst_i)
variable tmp_header : std_logic_vector(HEADER_SIZE - 1 downto 0);
variable local_ref_parift : std_logic;
variable local_parity_bit : std_logic;
begin -- process p_main_sm
if rst_i = '1' then -- asynchronous reset (active low)
rxstart_ind_o <= '0';
rxdata_valid_o <= '0';
rxend_ind_o <= '0';
stateID <= Idle;
data_counter <= (others => '0');
rxcca_ind_o <= '0';
rxcca_ind_internal <= '0';
frame_counter <= (others => '0');
rxdatarate_z1 <= (others => '0');
rxlength_z1 <= (others => '0');
header <= (others => '0');
rxdata_o <= '0';
rxdata_o_zm1 <= '0';
rxdata_valid_o_zm1 <= '0';
rxerror_o_zm1 <= (others => '0');
tsf_timeval <= (others => '0');
error_bit_counter <= (others => '0');
add_error_flag <= '0';
rx_frame_counter <= (others => '0');
parity_error_flag <= '0';
state_debug <= (others => '0');
inc_datacounter_flag <= '0';
rst_data_counter_flag <= '0';
registered_preambles_num <= (others => '0');
registered_error_freq <= (others => '0');
registered_cca_trig_point <= (others => '0');
registered_corr_bit_loc <= (others => '0');
rxerror_o <= (others => '0');
rxdatarate_o <= (others => '0');
rxlength_o <= (others => '0');
elsif rxclk_i'event and rxclk_i = '1' then -- rising clock edge
-- create pulse signals
rxstart_ind_o <= '0';
rxdata_valid_o_zm1 <= '0';
rxend_ind_o <= '0';
inc_datacounter_flag <= '0';
rst_data_counter_flag <= '0';
-- registered inputs
registered_preambles_num <= tmp_preambles_num;
registered_error_freq <= tmp_error_freq;
registered_cca_trig_point <= tmp_cca_trig_point;
registered_corr_bit_loc <= tmp_corr_bit_loc;

-- data counter updated on the inc_counter_flag
if rst_data_counter_flag = '1' then
data_counter <= (others => '0');
elsif inc_datacounter_flag = '1' then
data_counter <= data_counter + 1;
end if;

if clear_error_reg = '1' then
rxerror_o_zm1 <= (others => '0');
end if;

-- set error bit if a colision is detected
if error_data_enable = '1' then
rxerror_o_zm1(3) <= '1';
end if;

-- detect fifo full
if full_a = '1' then
rxerror_o_zm1(1) <= '1';
end if;
if full_b = '1' then
rxerror_o_zm1(2) <= '1';
end if;

if common_data_valid = '0' then
stateID <= Idle;
if stateID /= Idle then
rxend_ind_o <= '1';
--rxcca_ind_o <= '0';
rxcca_ind_internal <= '0';
rst_data_counter_flag <= '1';
end if;
else

if data_valid = '1' then

case stateID is
when Idle =>
inc_datacounter_flag <= '1';

tsf_timeval <= tsf_reg;
rx_frame_counter <= rx_frame_counter + 1;
-- count the number of frames
frame_counter <= frame_counter + 1;
stateID <= WaitRxStart;
state_debug <= "000";

when WaitRxStart =>
inc_datacounter_flag <= '1';
if data_counter = registered_cca_trig_point then
--rxcca_ind_o <= '1';
rxcca_ind_internal <= '1';
stateID <= WaitStartData;
state_debug <= "001";
end if;


when WaitStartData =>
inc_datacounter_flag <= '1';
if data_counter = registered_preambles_num then
rst_data_counter_flag <= '1';
if registered_error_freq /= 0 then
if frame_counter >= registered_error_freq then
add_error_flag <= '1';
error_bit_counter <= registered_corr_bit_loc;
frame_counter <= (others => '0');
end if;
end if;
state_debug <= "010";
stateID <= ReceiveHeader;
end if;



when ReceiveHeader =>
inc_datacounter_flag <= '1';
-- if the data bit counter is where the error should be
-- introduced flip the bit corresponding to the bit location
if (add_error_flag = '1' and data_counter =
error_bit_counter) then
tmp_header := header(HEADER_SIZE - 2 downto 0) &
not(data_val);
add_error_flag <= '0';
rxerror_o_zm1(4) <= '1';
else
tmp_header := header(HEADER_SIZE - 2 downto 0) & data_val;
end if;

if data_counter = HEADER_SIZE - 1 then

rxdatarate_z1 <= tmp_header(HEADER_SIZE - 1 downto
HEADER_SIZE - TXDR_SIZE);
rxlength_z1 <=
tmp_header(HEADER_SIZE - TXDR_SIZE - 1 downto
HEADER_SIZE - TXDR_SIZE - DATALEN_SIZE);
local_parity_bit :=
tmp_header(HEADER_SIZE - TXDR_SIZE - DATALEN_SIZE - 1);
local_ref_parift := '0';

for kk in HEADER_SIZE - 1 downto
HEADER_SIZE - TXDR_SIZE - DATALEN_SIZE loop
local_ref_parift := local_ref_parift xor tmp_header(kk);
end loop; -- kk

if local_ref_parift /= local_parity_bit then
parity_error_flag <= '1';
else
parity_error_flag <= '0';
end if;
stateID <= WaitSettle;
state_debug <= "011";
end if;
header <= tmp_header;




when ReceiveData =>
inc_datacounter_flag <= '1';
-- bit counter matches the register indicated value
if (add_error_flag = '1'
and data_counter = error_bit_counter) then

rxdata_o_zm1 <= not(data_val);
add_error_flag <= '0';
rxerror_o_zm1(5) <= '1';
else
rxdata_o_zm1 <= data_val;
end if;
rxdata_valid_o_zm1 <= '1';

when others => null;
end case;
end if; -- if data_valid = '1' then

if stateID = WaitSettle then
if parity_error_flag = '1' then
rxerror_o_zm1(0) <= '1';
end if;
-- pull the rxstart_ind_o high
rxstart_ind_o <= '1';
state_debug <= "100";
stateID <= ReceiveData;

end if;

end if;

rxcca_ind_o <= rxcca_ind_internal;
rxdata_o <= rxdata_o_zm1;
rxdata_valid_o <= rxdata_valid_o_zm1;
rxerror_o <= rxerror_o_zm1;
rxdatarate_o <= rxdatarate_z1;
rxlength_o <= rxlength_z1;

end if;
end process p_main_sm;
 
K

KJ

This has nothing to do with the question about the counter but I'm
always amazed when I see the following line of code (copied from the
post)

elsif rxclk_i'event and rxclk_i = '1' then -- rising clock edge

instead of

elsif rising_edge(rxclk_i) then

The 'rising_edge' function is defined in the same ieee library where
'std_logic' is. It's much cleaner, more correct and doesn't require
comments to know what it does.

KJ
 
K

KJ

OK, now to be back ON topic this time. The posted question was...
Post synthesis report from ISE 8.1 (xst), tells me that it recognised
frame_counter as a register. Shouldn't frame_counter be recognised as a
counter to be the optimum design. My question is why this is happening
and also is there any way to tell the xst to recognise this as a counter.

My question to you are:
- Why do you think how ISE 8.1 calls it matters? (Hint: It doesn't)
- What do you think a counter consists of? (Hint: Registers and
combinatorial logic)

If the code in your design
- Meets all of the requirements of your application (i.e. function,
performance, timing, power, etc.)
- And all the constraints (part, package, airflow, etc.)

then it don't sweat what ISE calls it. If you want an 'optimum' design
then you first you have to define your 'optimization function' and that
will go right back to the requirements and constraints.

KJ
 
M

Martin Gagnon

This has nothing to do with the question about the counter but I'm
always amazed when I see the following line of code (copied from the
post)

elsif rxclk_i'event and rxclk_i = '1' then -- rising clock edge

instead of

elsif rising_edge(rxclk_i) then

The 'rising_edge' function is defined in the same ieee library where
'std_logic' is. It's much cleaner, more correct and doesn't require
comments to know what it does.

For myself.. I don't need a comment to understand what it's do... it's
obvious.. If there's an event on the signal and after this event you
look at the signal and the value is one.. for sure it's a rising edge..

I guest.. a lot of people use that because they get used to it long time
ago when "rising_edge" keyword was not known by their old legacy vhdl
interpreter.. The "if clk'event and clk = '1'" way is the original
way to define a rising edge (or falling edge) in vhdl. May be some
others people start with something that support it but learn it at
school the way the teacher use it... who knows..

Personnally.. I don't care... I understand both way and both generate
exactly the same logic.
 
D

Dave Pollum

Sanka said:
My appologies.

This code is implemented in a process and this particular process is
very large, but the process where the counter is implemented as follows.

Sanka

p_main_sm : process (rxclk_i, rst_i)
variable tmp_header : std_logic_vector(HEADER_SIZE - 1 downto 0);
variable local_ref_parift : std_logic;
variable local_parity_bit : std_logic;
begin -- process p_main_sm
if rst_i = '1' then -- asynchronous reset (active low)
rxstart_ind_o <= '0';
rxdata_valid_o <= '0';
rxend_ind_o <= '0';
stateID <= Idle;
data_counter <= (others => '0');
rxcca_ind_o <= '0';
rxcca_ind_internal <= '0';
frame_counter <= (others => '0');
rxdatarate_z1 <= (others => '0');
rxlength_z1 <= (others => '0');
header <= (others => '0');
rxdata_o <= '0';
rxdata_o_zm1 <= '0';
rxdata_valid_o_zm1 <= '0';
rxerror_o_zm1 <= (others => '0');
tsf_timeval <= (others => '0');
error_bit_counter <= (others => '0');
add_error_flag <= '0';
rx_frame_counter <= (others => '0');
parity_error_flag <= '0';
state_debug <= (others => '0');
inc_datacounter_flag <= '0';
rst_data_counter_flag <= '0';
registered_preambles_num <= (others => '0');
registered_error_freq <= (others => '0');
registered_cca_trig_point <= (others => '0');
registered_corr_bit_loc <= (others => '0');
rxerror_o <= (others => '0');
rxdatarate_o <= (others => '0');
rxlength_o <= (others => '0');
elsif rxclk_i'event and rxclk_i = '1' then -- rising clock edge
-- create pulse signals
rxstart_ind_o <= '0';
rxdata_valid_o_zm1 <= '0';
rxend_ind_o <= '0';
inc_datacounter_flag <= '0';
rst_data_counter_flag <= '0';
-- registered inputs
registered_preambles_num <= tmp_preambles_num;
registered_error_freq <= tmp_error_freq;
registered_cca_trig_point <= tmp_cca_trig_point;
registered_corr_bit_loc <= tmp_corr_bit_loc;

-- data counter updated on the inc_counter_flag
if rst_data_counter_flag = '1' then
data_counter <= (others => '0');
elsif inc_datacounter_flag = '1' then
data_counter <= data_counter + 1;
end if;

if clear_error_reg = '1' then
rxerror_o_zm1 <= (others => '0');
end if;

-- set error bit if a colision is detected
if error_data_enable = '1' then
rxerror_o_zm1(3) <= '1';
end if;

-- detect fifo full
if full_a = '1' then
rxerror_o_zm1(1) <= '1';
end if;
if full_b = '1' then
rxerror_o_zm1(2) <= '1';
end if;

if common_data_valid = '0' then
stateID <= Idle;
if stateID /= Idle then
rxend_ind_o <= '1';
--rxcca_ind_o <= '0';
rxcca_ind_internal <= '0';
rst_data_counter_flag <= '1';
end if;
else

if data_valid = '1' then

case stateID is
when Idle =>
inc_datacounter_flag <= '1';

tsf_timeval <= tsf_reg;
rx_frame_counter <= rx_frame_counter + 1;
-- count the number of frames
frame_counter <= frame_counter + 1;
stateID <= WaitRxStart;
state_debug <= "000";

when WaitRxStart =>
inc_datacounter_flag <= '1';
if data_counter = registered_cca_trig_point then
--rxcca_ind_o <= '1';
rxcca_ind_internal <= '1';
stateID <= WaitStartData;
state_debug <= "001";
end if;


when WaitStartData =>
inc_datacounter_flag <= '1';
if data_counter = registered_preambles_num then
rst_data_counter_flag <= '1';
if registered_error_freq /= 0 then
if frame_counter >= registered_error_freq then
add_error_flag <= '1';
error_bit_counter <= registered_corr_bit_loc;
frame_counter <= (others => '0');
end if;
end if;
state_debug <= "010";
stateID <= ReceiveHeader;
end if;



when ReceiveHeader =>
inc_datacounter_flag <= '1';
-- if the data bit counter is where the error should be
-- introduced flip the bit corresponding to the bit location
if (add_error_flag = '1' and data_counter =
error_bit_counter) then
tmp_header := header(HEADER_SIZE - 2 downto 0) &
not(data_val);
add_error_flag <= '0';
rxerror_o_zm1(4) <= '1';
else
tmp_header := header(HEADER_SIZE - 2 downto 0) & data_val;
end if;

if data_counter = HEADER_SIZE - 1 then

rxdatarate_z1 <= tmp_header(HEADER_SIZE - 1 downto
HEADER_SIZE - TXDR_SIZE);
rxlength_z1 <=
tmp_header(HEADER_SIZE - TXDR_SIZE - 1 downto
HEADER_SIZE - TXDR_SIZE - DATALEN_SIZE);
local_parity_bit :=
tmp_header(HEADER_SIZE - TXDR_SIZE - DATALEN_SIZE - 1);
local_ref_parift := '0';

for kk in HEADER_SIZE - 1 downto
HEADER_SIZE - TXDR_SIZE - DATALEN_SIZE loop
local_ref_parift := local_ref_parift xor tmp_header(kk);
end loop; -- kk

if local_ref_parift /= local_parity_bit then
parity_error_flag <= '1';
else
parity_error_flag <= '0';
end if;
stateID <= WaitSettle;
state_debug <= "011";
end if;
header <= tmp_header;




when ReceiveData =>
inc_datacounter_flag <= '1';
-- bit counter matches the register indicated value
if (add_error_flag = '1'
and data_counter = error_bit_counter) then

rxdata_o_zm1 <= not(data_val);
add_error_flag <= '0';
rxerror_o_zm1(5) <= '1';
else
rxdata_o_zm1 <= data_val;
end if;
rxdata_valid_o_zm1 <= '1';

when others => null;
end case;
end if; -- if data_valid = '1' then

if stateID = WaitSettle then
if parity_error_flag = '1' then
rxerror_o_zm1(0) <= '1';
end if;
-- pull the rxstart_ind_o high
rxstart_ind_o <= '1';
state_debug <= "100";
stateID <= ReceiveData;

end if;

end if;

rxcca_ind_o <= rxcca_ind_internal;
rxdata_o <= rxdata_o_zm1;
rxdata_valid_o <= rxdata_valid_o_zm1;
rxerror_o <= rxerror_o_zm1;
rxdatarate_o <= rxdatarate_z1;
rxlength_o <= rxlength_z1;

end if;
end process p_main_sm;
p_main_sm : process (rxclk_i, rst_i)
...
begin -- process p_main_sm
if rst_i = '1' then -- asynchronous reset (active low)

In the above line, either the comment is wrong or the code is!
-Dave Pollum
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top