0

What I'm trying to do is pretty simple, just generating a pulse from a basic counter. My code is shown below. My question is if there's an efficient way of comparing a std_logic_vector and an integer? I only need to compare them at that one instance in the process. Also, can you do aritmetic on a 4 bit signal as shown in my code? DO you need a specific library?

signal Top16: std_logic; -- 1 clk spike at 16x baud rate    
signal Div16: std_logic_vector(3 downto 0);

DIVISOR: natural := 120 -- Can be 120 or 60, depending on user preference.    
------------------------------------------------------------------------

    process (RST, LCLK_MULT_BUFG)
    begin
        if RST='1' then
            Top16 <= '0';  --1 bit signal
            Div16 <= x"0";  -- 4 bit signal
        elsif rising_edge(LCLK_MULT_BUFG) then
            Top16 <= '0';
                if Div16 = Divisor then  -----> signal to integer comparison?
                    Div16 <= 0;
                    Top16 <= '1';  
                else
                    Div16 <= Div16 + 1;   -----arithmetic on std_logic_vector??
                end if;
        end if;

EDIT:

The number of bits within the Div16 std_logic_vector will vary depending on the size of Divisor chosen (shown below). How to correctly format this? What libraries will be needed?

DIVISOR: natural := 120 -- Can be 120 or 60, depending on user preference.
constant COUNTER_BITS : natural := integer(ceil(log2(real(DIVISOR))));
signal Div16: std_logic_vector(COUNTER_BITS);  

2 Answers 2

3

If at all possible, avoid the non-standard std_logic_unsigned library. It would be better to use numeric_std and declare Div16 as unsigned.

signal Div16: unsigned(3 downto 0);

Then your comparison and arithmetic should simply work. And of course it's synthesisable.

Your bonus question should also be synthesisable though DIVISOR ought to be a CONSTANT so that it can be evaluated at compile time, and I think you meant

signal Div16: unsigned(COUNTER_BITS - 1 downto 0);  
Sign up to request clarification or add additional context in comments.

3 Comments

Is that signal still fully synthesizable? Also added an edit above for another conversion issue, would really appreciate if you could check that one out too!
am still recieving these 2 errors when I try what you say: "ERROR:HDLCompiler:69 - Line 62: <ceil> is not declared." "ERROR:HDLCompiler:622 - Line 62: Near integer ; type conversion expression type cannot be determined uniquely"
Since ceil() was in your code I assumed you'd already found it. It's in the ieee.math_real library so just use that : use ieee.math_real.all; with the other use clauses. If you don't want to use math_real, a ceil function is trivial to write. The second error is just a consequence of not finding ceil.
0

For the arithmetic you can use std_logic_unsigned. This library contains the following functions:

function "+"(L: STD_LOGIC_VECTOR; R: INTEGER) return STD_LOGIC_VECTOR;
function "+"(L: INTEGER; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;

For the comparison you can just leave it like this if you are using std_logic_unsigned. This library contains the following functions:

function "="(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN;
function "="(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN;

You could also define Div16 as unsigned and then use numeric_std. This library contains the following functions for comparison:

function "=" ( L: NATURAL; R: UNSIGNED) return BOOLEAN;
function "=" ( L: UNSIGNED; R: NATURAL) return BOOLEAN;

And for the addition:

function "+" ( L: UNSIGNED; R: NATURAL) return UNSIGNED;
function "+" ( L: NATURAL; R: UNSIGNED) return UNSIGNED;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.