Author Topic: 0 logic elements in vhdl code  (Read 3319 times)

0 Members and 1 Guest are viewing this topic.

Offline swampythe47Topic starter

  • Newbie
  • Posts: 8
  • Country: in
0 logic elements in vhdl code
« on: August 02, 2018, 05:42:17 am »
Can anyone please help me with my code? I am able to compile code but i am getting 0 logic elements. Its not working on FPGA board(cyclone 2).
I am attaching 5 of my codes files.

P.s.:-Ultrasonic is my top level entity.
 

Offline Daixiwen

  • Frequent Contributor
  • **
  • Posts: 367
  • Country: no
Re: 0 logic elements in vhdl code
« Reply #1 on: August 02, 2018, 08:53:45 am »
I haven't looked at all your code, but for starters in the trigger generator you place the code in a process(clk) but after that you didn't put a clock edge trigger. Either you write a clocked process and include a check for the clock edge in the process, or you make a combinatorial process but then you must put all the inputs in the process sensitivity list. With your code the synthesizer will ignore the (clk) sensitivity list and make a combinatorial process. This will give different results on the FPGA than what you could see in simulation.
I see a circular reference on the reset signal between the trigger generator and the counter. You use the counter value to create a combinatorial reset signal, that is used itself to asynchronously reset the counter. I'm not sure how the synthesizer will interpret that but it probably won't be what you want.
Did you have a look at all the warnings from the compilation process? If it removed all your logic, you will probably find the reason in the compiler report.
Oh and I almost forgot. I know there are lots of example (even text books) that use the ieee.std_logic_unsigned and ieee.std_logic_signed libraries but you really shouldn't. They are not standard libraries, and it becomes a mess when you will need to start mixing signed and unsigned values in your design. It is a lot better to use the ieee.numeric_std library and use the "unsigned" type for your std_logic_vector signals.
 
The following users thanked this post: swampythe47

Offline iMo

  • Super Contributor
  • ***
  • Posts: 5160
  • Country: bt
Re: 0 logic elements in vhdl code
« Reply #2 on: August 02, 2018, 10:43:14 am »
That happens to me usually when I mess with clock names across the source. No clock, no fun :)

Try to rename "clk" in your Distance.. BCD.. Counter.. components to "fpgaclk" your entity ultrasonic uses (ultrasonic.txt). Or something like that.

PS: as mentioned above you have to look into your log, look at Warnings, you have to find something like:
.. "clk" signal not found/used/wired, all your logic in this component/entity has been optimized out..

I do not use Altera, nor vhdl, so take it as a hint only :)
« Last Edit: August 02, 2018, 11:00:21 am by imo »
Readers discretion is advised..
 
The following users thanked this post: swampythe47

Offline AndyC_772

  • Super Contributor
  • ***
  • Posts: 4281
  • Country: gb
  • Professional design engineer
    • Cawte Engineering | Reliable Electronics
Re: 0 logic elements in vhdl code
« Reply #3 on: August 02, 2018, 11:03:22 am »
This is exactly the sort of problem you can easily solve with a simulator. Generate a top level component which provides a clock and any other trigger signals your design requires, then look through to see which signals aren't doing what you expect.

The level of complexity of this design is about at the point where you'll struggle to spot problems 'by inspection', especially since you've divided up an otherwise simple project into a set of individual components. This makes it unnecessarily complicated, IMHO.

If you're using Altera then the free version of ModelSim is the way forward. Other simulators are, of course, available.

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2812
  • Country: nz
Re: 0 logic elements in vhdl code
« Reply #4 on: August 02, 2018, 10:40:16 pm »
Serious question - why is there no indentation in your source code? Is it how you converted it to text, or do you truly not see the value of indentation?

Compare the original:
Code: [Select]
library ieee;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_1164.all;

entity BCD_converter is
port(Distance_input:in std_logic_vector(8 downto 0);
hundreds:out std_logic_vector(3 downto 0);
tens:out std_logic_vector(3 downto 0);
unit:out std_logic_vector(3 downto 0));
end BCD_converter;

architecture bcdarch of BCD_converter is
begin

process(Distance_input)
variable bcd:std_logic_vector(20 downto 0);
begin
bcd:=(others=>'0');
bcd(8 downto 0):=Distance_input;

for i in 0 to 8 loop
bcd(19 downto 0):=bcd(18 downto 0)&'0';
if(i<8 and bcd(12 downto 9)>"0100") then
bcd(12 downto 9):=bcd(12 downto 9)+"0011";
end if;

if(i<8 and bcd(16 downto 13)>"0100") then
bcd(16 downto 13):=bcd(16 downto 13)+"0011";
end if;
if(i<8 and bcd(20 downto 17)>"0100") then
bcd(20 downto 17):=bcd(20 downto 17)+"0011";
end if;
end loop;
hundreds<=bcd(20 downto 17);
tens<=bcd(16 downto 13);
unit<=bcd(12 downto 9);
end process;
end architecture;

and

Code: [Select]
library ieee;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_1164.all;

entity BCD_converter is
  port(Distance_input:in std_logic_vector(8 downto 0);
       hundreds:out std_logic_vector(3 downto 0);
       tens:out std_logic_vector(3 downto 0);
       unit:out std_logic_vector(3 downto 0));
end BCD_converter;

architecture bcdarch of BCD_converter is
  begin

process(Distance_input)
    variable bcd:std_logic_vector(20 downto 0);
  begin
    bcd:=(others=>'0');
    bcd(8 downto 0):=Distance_input;

    for i in 0 to 8 loop
        bcd(19 downto 0):=bcd(18 downto 0)&'0';
        if(i<8 and bcd(12 downto 9)>"0100") then
            bcd(12 downto 9):=bcd(12 downto 9)+"0011";
        end if;

        if(i<8 and bcd(16 downto 13)>"0100") then
            bcd(16 downto 13):=bcd(16 downto 13)+"0011";
        end if;
        if(i<8 and bcd(20 downto 17)>"0100") then
            bcd(20 downto 17):=bcd(20 downto 17)+"0011";
        end if;
    end loop;
    hundreds<=bcd(20 downto 17);
    tens<=bcd(16 downto 13);
    unit<=bcd(12 downto 9);
  end process;
end architecture;

I find the latter far easier to see what is going on, and see where it "has the wrong shape". I've seen this happen a bit lately, and am interested to find if it is a cultural thing, or a reaction to coding in Python....

Strangely enough, although it is missing the "if rising_edge(clk) then" it will most likely work in simulation - the inputs will change, the clock will change, and the outputs will change, but as you are discovering there is a big simulation vs implementation mismatch waiting to get you.

Even with the correct clocking added, the BCD conversion algorithm isn't very good for FPGA implementation. Without understanding the algorithm it is is obvious it will be both very slow, and use a lot of resources - the worst of both worlds

Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 
The following users thanked this post: swampythe47

Offline swampythe47Topic starter

  • Newbie
  • Posts: 8
  • Country: in
Re: 0 logic elements in vhdl code
« Reply #5 on: August 03, 2018, 01:36:59 pm »
I am now getting the logic elements but no output is seen as i assigning led pins as output
 

Online rstofer

  • Super Contributor
  • ***
  • Posts: 9935
  • Country: us
Re: 0 logic elements in vhdl code
« Reply #6 on: August 03, 2018, 02:23:48 pm »
As I understand the BCD converter, there is only an 8 bit input and 3 each 4 bit outputs.  I would implement that as 3 lookup tables in initialized RAM.  No logic at all.

In Xilinx Vivado, it is easy to read the values from a file during synthesis

Here is some excellent initialization code from hamster_nz that reads a hex file during synthesis:

Code: [Select]
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use STD.textio.all;
use ieee.std_logic_textio.all;

entity VectorROM is
    generic (
        SIZE        : integer := 32;
        ADDR_WIDTH  : integer := 5;
        COL_WIDTH   : integer := 16;
        NB_COL      : integer := 1;
        FILENAME    : STRING  := "Vector.hex"
    );
    port (
        clk         : in std_logic;
        LD_VECTOR   : in std_logic;
        addr        : in std_logic_vector(ADDR_WIDTH-1 downto 0);
        do          : out std_logic_vector(NB_COL*COL_WIDTH-1 downto 0));
    end VectorROM;
   
architecture behavioral of VectorROM is
    type ram_type is array (SIZE-1 downto 0) of std_logic_vector (NB_COL*COL_WIDTH-1 downto 0);
 
     impure function ocram_ReadMemFile(FileName : STRING) return ram_type is
        file FileHandle         : TEXT open READ_MODE is FileName;
        variable CurrentLine    : LINE;
        variable TempWord       : std_logic_vector(15 downto 0);
        variable Result         : ram_type;
    begin
        for i in 0 to 1024 loop
            exit when endfile(FileHandle);
           
            readLine(FileHandle, CurrentLine);
            hread(CurrentLine, TempWord);
            -- Result(i)   := resize(TempWord, 16);
            Result(i) := TempWord;
        end loop;
       
        return Result;
    end function;
     
    signal RAM      : ram_type := ocram_ReadMemFile(FILENAME);
--     
-- this is where the RAM is accessed by high level logic
--
begin
    process(clk,LD_VECTOR)
    begin
        if rising_edge(clk) then
            if LD_VECTOR = '1' then
                do <= RAM(conv_integer(addr));
            end if;
        end if;
    end process;

end behavioral;


And a piece of the .hex file

Code: [Select]
2001
c000
0186
0000
0000
0000
...

ETA:

Maybe the easy way is to declare the memory array as 256 words of 12 bits and use 3 hex digits in the file to define the contents of RAM.  Probably have to change COL_WIDTH.

« Last Edit: August 03, 2018, 02:34:27 pm by rstofer »
 

Offline swampythe47Topic starter

  • Newbie
  • Posts: 8
  • Country: in
Re: 0 logic elements in vhdl code
« Reply #7 on: August 05, 2018, 06:14:17 am »
I guess there ismsome problem in my logic. Can anyone please rectify and tell me?
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2812
  • Country: nz
Re: 0 logic elements in vhdl code
« Reply #8 on: August 05, 2018, 06:39:18 am »
Which bit are you having issues with? What are you attempting to do? What is happening, and what isn't?

 I will give you some good hints. but I wont write the code...

Also, I tend to match the reply to the amount of information you give.... my time is as valuable as yours, So a brief post will usually only get a brief reply, (unless it is particularly insightful, then I will rant forever)
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2812
  • Country: nz
Re: 0 logic elements in vhdl code
« Reply #9 on: August 05, 2018, 08:24:09 am »
I guess there ismsome problem in my logic. Can anyone please rectify and tell me?

What will most likely be the easiest is to work out a binary to BCD algorithm in a language you know, but under constraints that force you to write like it is a hardware description language.

Once you have a suitable algorithm, the actual VHDL implementation will be easy. If you can't express the algorithm in a language you know, then you will have a hard time trying to implement in VHDL.

To this end, you able to code & compile in C? Are you able to write a function that takes an unsigned integer between 0 and 511 parameter, and returns the same value, but in BCD?

Here is my example, to give you an idea:

Code: [Select]
unsigned my_module(unsigned input) {
  unsigned rtn = 0;
  rtn  = (input/100)%10;
  rtn *= 16;
  rtn += (input/10)%10;
  rtn *= 16;
  rtn += input%10;
  return rtn;
}

You don't have to use that code, anything that works will be fine.

All we need is a program that shows what the return value from "my_module(500)" is, in hexadecimal? (It should be 0x500)

If you want to use a different language to do your decimal to BCD conversion, that is fine - I know quite a few. All we just need a working bit of code that you can post in your reply.

Once you post your reply, I'll give you a set of restrictions that you need to follow in your 'my_module()' function, that reflect writing code for an FPGA.
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline swampythe47Topic starter

  • Newbie
  • Posts: 8
  • Country: in
Re: 0 logic elements in vhdl code
« Reply #10 on: August 07, 2018, 12:57:10 pm »
I am nit getting any response. I just want you to check whether my coding logic is correct or not?
 

Offline emece67

  • Frequent Contributor
  • **
  • !
  • Posts: 614
  • Country: 00
Re: 0 logic elements in vhdl code
« Reply #11 on: August 07, 2018, 02:41:53 pm »
.
« Last Edit: August 19, 2022, 01:55:12 pm by emece67 »
 

Offline emece67

  • Frequent Contributor
  • **
  • !
  • Posts: 614
  • Country: 00
Re: 0 logic elements in vhdl code
« Reply #12 on: August 07, 2018, 02:56:42 pm »
.
« Last Edit: August 19, 2022, 01:55:19 pm by emece67 »
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2812
  • Country: nz
Re: 0 logic elements in vhdl code
« Reply #13 on: August 07, 2018, 09:46:20 pm »
Even if you have the algorithm written in any programming language, you still have a hard road ahead if you have not thought such algorithm keeping in mind that it will, ultimately, be implemented on an FPGA. In your example, the / and % operators will be a PITA if you want them in the FPGA.

I'm still not sure about the intent of the code posted by the OP, I think that it tries to measure some distance (maybe measuring a time with a counter) and then convert such result to BCD. If such is the target of the circuit, then it may be much better to, directly, use a BCD counter to measure the time/distance. This way the design reduces to coding a 1-digit, cascadable, BCD counter and instantiating 3 of them. No need for any binary to BCD conversion nor for "exotic" (in the HDL sense) / and % operators.

Regards.

Fully agree... but I'm not going to bother helping somebody who either doesn't understand what they are trying to do or can't be bothered to work through the problem.

Once we had an idea of what the OP was trying to do, I would add the following constraints on them:

Expensive operations:
* You are not to use division or modulus operators. These are very, very expensive operations in an FPGA.
* You should avoid multiplication if possible - an FPGA may have only a dozen or so multiplier blocks, so they shouldn't be wasted on trivial things.

Cheap operations:
* Bitshifts are free
* Logical AND/OR/NOT operations are very inexpensive
* Addition / subtraction are also inexpensive.

FPGAs have no 'stack' or temporary storage:
* FPGAs don't have a stack so all variables need to be declared external to the function. In FPGAs storage gets implemented as a flip-flops in the FPGA fabric, and are statically allocated at 'build' time.
* You can only assign a variable once as you pass through your function - this is the same restriction as a clock edge only allows you to update a flip-flop once per cycle.
* FPGAs have a limited amount of flip-flops, so avoiding excessive variables is good.

Latency and lopping
* You only get one loop ('for' or 'while', whatever). It has to be in your 'main() function'
* Data can take many cycles to flow through your BCD conversion function as required.

Eventually I was hoping to get to something like this for the main():
Code: [Select]
int main(int c, char *argv[])
{
  unsigned int test_case = 0x1F4;  /* should convert to 0x500 */
  while(1) {
     unsigned output;
     output = my_module2(test_case);
     printf("0x%03x  => 0x%03x\n", test_case, output);
     sleep(1);
  }
  return 0;
}

And this for the BCD conversion (an ugly slow, but perfectly workable way):
Code: [Select]
unsigned last       = 0;
unsigned count      = 0;
unsigned ones       = 0;
unsigned tens       = 0;
unsigned hundreds   = 0;
unsigned converting = 0;
unsigned rtn        = 0;

unsigned my_module2(unsigned input) {
  /* Set the outputs */
  if(count == converting) {
    last = (hundreds<<8) | (tens<<4) | ones;
    rtn  = (hundreds<<8) | (tens<<4) | ones;
  } else {
    rtn  = last;
  }

  if(hundreds == 9 && tens == 9 && ones == 9) {
    /* Reset the counter */
    count = ones = tens =  hundreds = 0;
    /* Sample the input, so it can't change mid conversion */
    converting = input;
  } else {
    count++;
    if(tens == 9 && ones == 9) {
      hundreds++;
      tens = ones = 0;
    } else if(ones == 9) {
      tens++;
      ones = 0;
    } else {
      ones++;
    }
  }
  return rtn;
}

Converting that function to VHDL is a doddle, and will work.

However, a strange thing might happen, and the OP may have realized that this was a good solution:

Code: [Select]
unsigned bcd_table[512] = { 0x000, 0x001.... 0x511};

unsigned my_module2(unsigned input) {
  rtn = bcd_table[input&511]
  return rtn;
}

It complies with all the 'rules' and gets the job done with zero fuss, and near-zero latency. All the work is done offline in generating the table that maps inputs to outputs.
« Last Edit: August 07, 2018, 10:08:15 pm by hamster_nz »
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3246
  • Country: ca
Re: 0 logic elements in vhdl code
« Reply #14 on: August 07, 2018, 10:20:17 pm »
Expensive operations:
* You are not to use division or modulus operators. These are very, very expensive operations in an FPGA.

That's true, however, in the "bcd" case, it all should synthesise into a 9x12 LUT (9 inputs, 12 outputs). Given that the MSB of the result is always '0' and the LSB is straight wire from the LSB of the input, it is, in fact, 8x10 LUT - 10 slices in Xilinx (40 LUTs) - much simple than doing divisions.

Thus, you describe the behaviour with any operations on the variables you want, and the tools should use this information to figure out the set of values to put into the 8x10 LUT, shouldn't they?
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2812
  • Country: nz
Re: 0 logic elements in vhdl code
« Reply #15 on: August 07, 2018, 11:51:10 pm »
you describe the behaviour with any operations on the variables you want, and the tools should use this information to figure out the set of values to put into the 8x10 LUT, shouldn't they?
Of course, and they will if you use a lookup table (however it might end up in BRAM rather than LUTs depending if the design is clocked)

BCD conversion for big numbers (e.g. 12 bits or more) is when things get interesting, when you can't use lookup tables.

Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Online rstofer

  • Super Contributor
  • ***
  • Posts: 9935
  • Country: us
Re: 0 logic elements in vhdl code
« Reply #16 on: August 09, 2018, 02:12:32 pm »
However, a strange thing might happen, and the OP may have realized that this was a good solution:

Code: [Select]
unsigned bcd_table[512] = { 0x000, 0x001.... 0x511};

unsigned my_module2(unsigned input) {
  rtn = bcd_table[input&511]
  return rtn;
}

It complies with all the 'rules' and gets the job done with zero fuss, and near-zero latency. All the work is done offline in generating the table that maps inputs to outputs.

This really is the 'right' way to do the job for such a simple function, once converted to HDL.  Among other things, if I wrote the conversion as a table lookup, I might be able to understand how it works a year from now.

Earlier I showed an example of your code for building these tables from a file.  That works fine for my application where the table is object code for a CPU.  In the case of the converter, the table values are unlikely to change and there is no real reason for using an external file.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15340
  • Country: fr
Re: 0 logic elements in vhdl code
« Reply #17 on: August 09, 2018, 09:38:03 pm »
There's a problem with the way your counters are reset IMO.

Since you don't use any global reset, a lot of your signals are in an unknown state initially. This may or may not be a problem when using FPGAs (since they have internal global resets anyway), although the initial state of some signals may not be what you want. I always suggest using explicit reset signals. And if you're trying to simulate your code, you'll get errors (undefined states).

The reset signal of your counters rely on signals that themselves may have undefined inital states.

Besides, the 'Trigger_generator' looks fishy to me. Again, it has no global reset and the reset condition of the internal counter 'trigg' doesn't look right to me?
Code: [Select]
if(outputCounter=ms250And100us) THEN
resetCounter<='1';  -- the reset signal for the counter is active low, so the counter would get out of reset only when having the ms250And100us value?
else
resetCounter<='0';
end if;

There's a lot of room for improvement as well, I won't add to what has been said already. But what's up with the indentation and lack of whitespace? Was it in the process of copying your code for the forum or is it your habit of coding? If it's the latter, you may want to enter a VHDL obfuscation contest. :-DD
 

Online rstofer

  • Super Contributor
  • ***
  • Posts: 9935
  • Country: us
Re: 0 logic elements in vhdl code
« Reply #18 on: August 10, 2018, 12:46:48 am »
As to the BCD conversion, maybe this will work

Code: [Select]
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity BCD is
    Port ( Value : in  STD_LOGIC_VECTOR ( 7 downto 0);
           BCD   : out STD_LOGIC_VECTOR (11 downto 0));
end BCD;

architecture Behavioral of BCD is

type LookupTableType is array(0 to 255) of std_logic_vector(11 downto 0);
signal LookupTable : LookupTableType :=
        (x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009",
         x"010",x"011",x"012",x"013",x"014",x"015",x"016",x"017",x"018",x"019",
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009", -- change these lines
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009", -- too lazy to type proper
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009", -- values
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009",
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009",
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009",
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009",
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009",
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009",
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009",
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009",
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009",
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009",
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009",
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009",
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009",
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009",
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009",
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009",
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009",
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009",
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009", --
         x"000",x"001",x"002",x"003",x"004",x"005",x"006",x"007",x"008",x"009", -- down to here       
         x"250",x"251",x"252",x"253",x"254",x"255");
begin
    BCD <= LookupTable(to_integer(unsigned(Value)));
end Behavioral;

Note that most of the table initialization values are wrong.  I just copied and pasted my way through it, I wasn't interested enough to type the proper values 256 times.

I know this synthesizes but I didn't tie it to a constraints file and actually run it on a board.
« Last Edit: August 10, 2018, 12:48:36 am by rstofer »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf