Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6153033
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 23, 20262026-05-23T20:01:29+00:00 2026-05-23T20:01:29+00:00

Essentially, my question is: can this not be done any easier? ; and what

  • 0

Essentially, my question is: “can this not be done any easier?“; and what ‘this’ is, follows below (code too):

I wanted to have a sort of a ‘complement’ counter function, implemented in VHDL, which would basically invert/complement/not the counter value in each step, giving slightly richer bit patterns for testing. Of course, I wanted this as synthesizable (so the counter value could be possibly assigned to pins) and portable code (i.e. implemented only IEEE libraries, no STD_LOGIC_ARITH). I also don’t want to by default treat all as unsigned (so I’d like to avoid STD_LOGIC_UNSIGNED).

In brief, this counter could be described as: given initial value C[0], then values at each clock tick would be:

C[i+1] = not(C[i]) + ( ( C[i]<(Cmax/2) ) ? 0 : 1 )

… or given C is 16-bit wide (which will result with unsigned Cmax = 65535 and Cmax/2 = 32768), it could also be written as:

C[i+1] = 65535 - C[i] + ( ( C[i]<32768 ) ? 0 : 1 )

The trick here is that the counter should only increment once – if it increases for both complementary and ‘normal’ ranges, then no changes will happen (equation will ‘oscillate’ between two values).

 

So, given that the check C[i]<(Cmax/2) is basically the same as checking the most significant (15th) bit of C, I thought that I could easily implement something like this in VHDL using something like:

Y <= not(Y) + Y(15);

 

Boy, was I wrong about “easily” 🙂

First problem is that it is possible the above equation could end up at 65535+1, in which case the result will need 17 bits (i.e. overflow); in my case, I’d simply want to truncate/ignore any ‘carry bits’.

This leads into the problem of what to use:

  • std_logic_vector has complement not() defined; but it doesn’t have + (addition) defined
  • natural/integer may internally take up 32 bits, and as such bit width for them is not necesarilly specified; they support arithmetic +, but no complement not()
  • I tried unsigned too, had some problems also (cannot remember which)

The 15th (MSB) bit can only be extracted when Y is std_logic_vector, in which case, Y(15) is a single std_logic – but then, it needs to be converted to integer type, because otherwise addition + is not defined 😐

So, my current solution (below) first has two copies of the counter register; one is SIGNAL wCntReg : STD_LOGIC_VECTOR(15 DOWNTO 0); the other is SIGNAL tmp_na : natural. Then:

  • There are two clocks: one ‘master’ @ 50 MHz, the other is the ‘counter’ clock: the master 16-times frequency divided (3.125 MHz).
  • The ‘counter’ clock should activate calculation of counter values on falling edge
  • The calculation is performed via natural variable (which copies from the STD_LOGIC_VECTOR one)
  • Apparently, std_logic can only be converted to integer if its converted to std_logic_vector first (I was lucky to find the vectorize function on the net).

The nastiest part here was how to feed back the natural variable value, back to the STD_LOGIC_VECTOR one; the only working command I could construct is:

wCntReg <= std_logic_vector(to_unsigned(natural'pos(tmp_na), wCntReg'length));

…; however, note that this command basically ‘sets’ the value, which will be ‘effectuated’ next time this same command runs. Thus, it cannot run in the ‘counter’ clock process – in the code below, I have it in the faster ‘master’ clock process.

Finally, the code below does work (goes through behavioral simulation in ISE WebPack) – but, I’d still like to know if there is a more straightforward way to solve this.

Thanks in advance for any answers,
Cheers!

 

The code:

----------------------------------------------------------------------------------

library IEEE;
  use IEEE.STD_LOGIC_1164.ALL;
  -- use IEEE.STD_LOGIC_ARITH.ALL;
  -- use IEEE.STD_LOGIC_UNSIGNED.ALL;
  use IEEE.NUMERIC_STD.ALL;


ENTITY complement_count_test_tbw IS
END complement_count_test_tbw;

ARCHITECTURE testbench_arch OF complement_count_test_tbw IS

  -- http://www.ingenieurbuero-eschemann.de/downloads/ipicregs/example/vhdl/test/timer_regs_tb.vhd
  -- convert std_logic to std_logic_vector(0 downto 0)
  function vectorize(s: std_logic) return std_logic_vector is
  variable v: std_logic_vector(0 downto 0);
  begin
      v(0) := s;
      return v;
  end;


  -- DECLARE REGISTERS ==========================

  -- 'wires'
  SIGNAL wtCLK : std_logic := '0';

  -- counter register: 16 bit
  SIGNAL wCntReg : STD_LOGIC_VECTOR(15 DOWNTO 0) := (others => 'Z');

  -- temporary 'natural' copy of counter register
  -- http://www.velocityreviews.com/forums/t21700-std_logic_vector-to-unsigned-type-casting.html
  SIGNAL tmp_na : natural;


  -- clock parameters
  constant PERIODN : natural := 20; -- can be real := 20.0;
  constant PERIOD : time := PERIODN * 1 ns;
  constant DUTY_CYCLE : real := 0.5;
  constant OFFSET : time := 100 ns;

  -- freq divisor; with initial values
  constant fdiv : natural := 16;
  SIGNAL fdiv_cnt : natural := 1;
  SIGNAL wfdiv_CLK : std_logic := '0';

BEGIN

  -- initializations of connections:

  -- instances of components, and their wiring (port maps)...
  -- END instances of components, and their wiring (port maps)...


  -- PROCESSES (STATE MACHINES) CODE =========

  -- clock process for generating CLK
  PROCESS
  BEGIN

    WAIT for OFFSET;

    CLOCK_LOOP : LOOP
      wtCLK <= '0';
      -- MUST refresh counter reg here with value of tmp_na
      wCntReg <= std_logic_vector(to_unsigned(natural'pos(tmp_na), wCntReg'length));
      WAIT FOR (PERIOD - (PERIOD * DUTY_CYCLE));
      wtCLK <= '1';
      WAIT FOR (PERIOD * DUTY_CYCLE);
    END LOOP CLOCK_LOOP;
  END PROCESS;

  -- freq divided clock
  freq_divisor: PROCESS(wtCLK)
  BEGIN
    IF rising_edge(wtCLK) THEN -- posedge
      IF fdiv_cnt = fdiv THEN
        -- reset
        fdiv_cnt <= 1 ;
        wfdiv_CLK <= not(wfdiv_CLK);
      ELSE
        fdiv_cnt <= fdiv_cnt + 1;
      END IF;
    END IF;
  END PROCESS freq_divisor;



  -- sim: count
  PROCESS
  BEGIN

    WAIT for 10 ns;

    tmp_na <= 125;

    WAIT for 10 ns;


    TESTCOUNT_LOOP: LOOP

      -- change counter on negedge of freq. divided clock
      WAIT until falling_edge(wfdiv_CLK);

      tmp_na <= to_integer(unsigned(not(wCntReg))) + to_integer(unsigned(vectorize(wCntReg(15))));

      WAIT for 10 ns;

    END LOOP TESTCOUNT_LOOP;

  END PROCESS;

  -- END PROCESSES (STATE MACHINES) CODE =====

-- END IMPLEMENT ENGINE of 'CORE' ===============
END testbench_arch;
-- END ARCHITECTURE -----------------------------
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-23T20:01:30+00:00Added an answer on May 23, 2026 at 8:01 pm

    Firstly, full marks for avoiding not use std_logic_arith!

    If you define your vectors as unsigned then (outside of a process) all that is required is this:

      cn_plus_1 <= not cn when cn < halfc else (not cn) + 1;
    

    and you can assign cn_plus_1 to a std_logic_vector thus:

    wCntReg <= std_logic_vector(cn_plus_1);
    

    Here’s a couple of complete examples of VHDL idiomatic ways of doing it:

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    entity funny_counter1 is
        port (
            cn: IN unsigned(15 downto 0);
            cn_plus_1 : out unsigned(15 downto 0));
    end entity funny_counter1;
    
    architecture a1 of funny_counter1 is
        constant halfc : unsigned(cn'range) := (cn'high => '1', others => '0');
    begin  -- architecture a1
        cn_plus_1 <= not cn when cn < halfc else (not cn) + 1;
    end architecture a1;
    

    or in a synchronous process:

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    
    entity funny_counter is
        port (
            clk   : in  std_logic;
            reset : in  std_logic;
            cout  : out unsigned(15 downto 0));
    end entity funny_counter;
    
    architecture a1 of funny_counter is
        constant halfc : unsigned(cout'range) := (cout'high => '1', others => '0');
    begin
        process (clk) is
            variable c   : unsigned(15 downto 0);
            variable add : integer range 0 to 1;
        begin  -- process
            if rising_edge(clk) then  -- rising clock edge
                if reset = '1' then
                    c := (others => '0');
                else
                    add := 0;
                    if c < halfc then
                        add := 1;
                    end if;
                    c := (not c) + add;
                end if;
                cout <= c;
            end if;
        end process;
    end architecture a1;
    

    Whenever you find yourself converting a lot between std_logic_vectors and integers (or similar), you are usually working with actual numbers. Work with either unsigned/signed vectors or with integers. If you need a vector at the end of it all, convert it one and for all at the end. It’s not pleasant to look at necessarily. But first ask if the thing you are sending the value to ought to be using a numerical type of some sort on its interface. Only if it truly is a ‘bag-of-bits’ is a std_logic_vector the best type. The name wCntReg sound like a count value to me, so it should have a numeric type to my mind.

    This code you have:

    wCntReg <= std_logic_vector(to_unsigned(natural'pos(tmp_na), wCntReg'length));
    

    is slightly worse than it needs to be:

    wCntReg <= std_logic_vector(to_unsigned(tmp_na, wCntReg'length));
    

    ought to work fine.

    Finally, you comment on this only coming into effect on the next clock tick is how VHDL works – signals are only updated when some time passes (often this is only at the end of a process). If you want to make use of the new value before then, use a variable – they update straight away.

    So if your tempna were a variable, you could do the wCntReg assignment straight after.

    For completeness: another way around this (which is usually a kludge IME) is to wait for 0 ns; after the signal assignment. This causes some time to pass from the point of view of updates, so all other delta cycles will execute for the current time (including the signal assignment you want to propgate) time will move on (by 0ns!) and a new delta cycle can begin.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

This seems like a basic question, but I haven't found any clear answers. Essentially,
This is a design question, concrete code not submitted to protect my bottom. When
Essentially, the question is in the title. I have a ASP.NET MVC application, and
This questions involves 2 different implementations of essentially the same code. First, using delegate
This is not a specific question, instead I'm trying to get an idea of
Total noob here learning openGL and I don't have any code to post because
My question is essentially a simple one, though I'm looking for as in-depth an
My question is essentially the same as question 765054 on StackOverflow. I'm only asking
My question is essentially the same as the following one but the answer did
I have essentially a survey that is shown, and people answer questions a lot

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.