element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
FPGA
  • Technologies
  • More
FPGA
Forum Connecting Verilog to Synthesis
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join FPGA to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • State Verified Answer
  • Replies 12 replies
  • Answers 2 answers
  • Subscribers 546 subscribers
  • Views 2845 views
  • Users 0 members are here
Related

Connecting Verilog to Synthesis

mraureliusr
mraureliusr over 11 years ago

Hey everyone! Wish I had seen this group earlier.

 

I'm hoping there's a few here who are familiar with the Xilinx ISE. I'm finally making a concerted effort to learn Verilog and this time around I'm doing well. I'm grasping the language concepts well, and am enjoying the book I picked up from the local University library (public library is a bit short on HDL books!) called "Verilog for Digital Design" written by Frank Vahid and Roman Lysecky. Make sure to check for the 2002 edition, there are older versions as well. This book is the perfect blend of theory and practical code writing.

 

Anyway, I wanted to try implementing a simple design of my own, essentially recreating the functionality of four 74193 up/down binary counters. The inputs are four buttons, up, down, load and store. The load and store buttons control signals for a later stage of the design.

 

I wrote the counter module, then created a top level module and instantiated the     counter module. I simulated it with a simple test bench and it worked!! Amazing!

 

However, now I'm trying to implement it in my Spartan-3E FPGA and I'm having trouble figuring out the hierarchy of a typical design. Clearly the top level module interfaces with the actual pins, and then passes these states to the instantiated module. But how do I pick which pins connect to the top level module? I see that PlanAhead seems to implement this stage of the design but I'm confused on how to put it all together. I'm also having trouble connecting the counter module ports to the top level module. It keeps giving me errors for the output bus, saying something like it's not a proper lvalue? The counter module has the counter output declared as an output reg[15:0] ... is that incorrect? The top level module also has the actual output declared as an output reg, is it improper to commect these types together? I figured within the counter module that the output should be a reg ad not a wire, because it needs to hold its value. Plus the output needs to be manipulated directly and it seems a reg was the easiest way to do this


Perhaps these questions will be answered later in the book but the ISE/Xilinx specific problems won't be addressed as the author uses different software and never directly talks about specific brands. He does focus on both simulation and synthesis though, which is what I was looking for. Most books on Verilog place a heavy focus on simulation, and while I've discovered how useful simulation is, I have this Xilinx dev board that I want to play/learn with!


Thanks everyone for reading all that. image Will be happy to share more as I learn more. If it helps I can post my code here.

  • Sign in to reply
  • Cancel

Top Replies

  • johnbeetem
    johnbeetem over 11 years ago +1 suggested
    I've never used PlanAhead. I always use a User Constraint File (.ucf) to define the pinout. The easiest way is to start with a working .ucf as a template, and then modify it. For example, here is the UCF…
Parents
  • johnbeetem
    0 johnbeetem over 11 years ago

    I've never used PlanAhead.  I always use a User Constraint File (.ucf) to define the pinout.  The easiest way is to start with a working .ucf as a template, and then modify it.  For example, here is the UCF file for the Papilio One FPGA board from Gadget Factory: http://forum.gadgetfactory.net/index.php?/files/file/2-papilio-one-generic-ucf/

     

    Here's a simple 4-bit up-counter:

    module UpCounter(Pclk, K);

    input    Pclk;            // 32 MHz Papilio clock.

    output    [3:0] K;        // 4-bit counter;

    reg        [3:0] K;

     

    always @(posedge Pclk)

            K <= K + 1;

    endmodule 

     

    This is the root module, and the pins Pclk and K[3:0] are the external pins.

     

    Once I have this in a .v file, I create a UCF with the same module name, UpCounter.ucf.

    Here are the relevant lines:

     

    NET Pclk  LOC="P89"  | IOSTANDARD=LVCMOS33 | PERIOD=31.25ns;

    NET K<0> LOC="P58" | IOSTANDARD=LVTTL;

    NET K<1> LOC="P41" | IOSTANDARD=LVTTL;

    NET K<2> LOC="P34" | IOSTANDARD=LVTTL;

    NET K<3> LOC="P25" | IOSTANDARD=LVTTL;

     

    I use the notation K<i> to reference bit i of bus K.

     

    I typically use ISE Webpack 12.4, with XST for synthesis.

     

    ISE has a tool for interactively editing the pinout, but I find .ucf quicker since you can use standard text editor copy/paste and replacement operations.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
Reply
  • johnbeetem
    0 johnbeetem over 11 years ago

    I've never used PlanAhead.  I always use a User Constraint File (.ucf) to define the pinout.  The easiest way is to start with a working .ucf as a template, and then modify it.  For example, here is the UCF file for the Papilio One FPGA board from Gadget Factory: http://forum.gadgetfactory.net/index.php?/files/file/2-papilio-one-generic-ucf/

     

    Here's a simple 4-bit up-counter:

    module UpCounter(Pclk, K);

    input    Pclk;            // 32 MHz Papilio clock.

    output    [3:0] K;        // 4-bit counter;

    reg        [3:0] K;

     

    always @(posedge Pclk)

            K <= K + 1;

    endmodule 

     

    This is the root module, and the pins Pclk and K[3:0] are the external pins.

     

    Once I have this in a .v file, I create a UCF with the same module name, UpCounter.ucf.

    Here are the relevant lines:

     

    NET Pclk  LOC="P89"  | IOSTANDARD=LVCMOS33 | PERIOD=31.25ns;

    NET K<0> LOC="P58" | IOSTANDARD=LVTTL;

    NET K<1> LOC="P41" | IOSTANDARD=LVTTL;

    NET K<2> LOC="P34" | IOSTANDARD=LVTTL;

    NET K<3> LOC="P25" | IOSTANDARD=LVTTL;

     

    I use the notation K<i> to reference bit i of bus K.

     

    I typically use ISE Webpack 12.4, with XST for synthesis.

     

    ISE has a tool for interactively editing the pinout, but I find .ucf quicker since you can use standard text editor copy/paste and replacement operations.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
Children
  • mraureliusr
    0 mraureliusr over 11 years ago in reply to johnbeetem

    Awesome -- thanks for the info on the .ucf file. I found that the dev board I have came with .ucf files so I can import those and find what pins are connected to what.

     

    Here's the real problem I'm having, I'll paste my code below. I have a main.v, which does nothing else (at this point) but instantiate the counter, which is a module from counter.v. When trying to connect the ports, I keep getting the errors:

    ERROR:HDLCompilers:246 - "main.v" line 32 Reference to vector reg 'addr_Out' is not a legal net lvalue

    ERROR:HDLCompilers:102 - "main.v" line 32 Connection to output port 'count_Out' must be a net lvalue

     

    Here's the main.v:

     

    module main(

      input button_Up,

        input button_Down,

        input button_Reset,

        input button_Load,

        input button_Store,

        output reg [15:0] addr_Out,

        output reg [7:0] data_Out,

      input output_Enable

      );

     

    counter TestCount(button_Up, button_Down, button_Reset, output_Enable, addr_Out);

     

    endmodule

     

    And here's the counter.v:

     

    module counter(

        input b_Up,

        input b_Down,

        input Rst,

        input OE,

        output reg[15:0] count_Out

        );

     

     

    always @(posedge Rst)

      count_Out = 16'h0000;

     

    always @(posedge b_Up) begin

      if(count_Out == 16'hFFFF)

      count_Out <= 16'h0000;

      else

      count_Out <= count_Out + 1'b1;

      end

     

    always @(posedge b_Down) begin

      if(count_Out == 16'h0000)

      count_Out <= 16'hFFFF;

      else

      count_Out <= count_Out - 1'b1;

     

    end

    endmodule

     

    Sorry if the formatting got messed up a little. I know the counter module works correctly (at least in simulation) because I did a basic testbench with it. The main.v is declared as the 'top module'. I'm just wondering how I pass the connections to the outside world through the main.v into the instance of the counter. Or is there a more 'proper' way to do this? The examples I've seen so far seem to hint that you write all your module in a separate file, then instantiate them in the main module, and do all the connections between them as instances. This seems the 'neatest' way to do it (at least in my mind) however this might be completely wrong. I haven't gotten through the whole book yet, so there's a decent chance I'll find more information about this, but I'm just curious how you normally implement a design with multiple modules (which this will eventually have -- there will be a 7-segment display driver, and a couple other small glue logic modules).

     

    Thanks again John! I really appreciate the help!

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • mraureliusr
    0 mraureliusr over 11 years ago in reply to mraureliusr

    Oops, the

     

    always @(posedge Rst)

      count_Out <= 16'h0000;

     

    should have been a non-blocking assignment, like I just put above.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • mraureliusr
    0 mraureliusr over 11 years ago in reply to mraureliusr

    I think I may have solved it. I should have caught that the addr_Out can't be a reg, as it is being driven by a port, so it has to be a wire. Also, the errors I was getting after changing it to a wire was because the count_Out in counter.v was being driven by multiple always statements (that's me thinking sequentially instead of parallel, years of C...)

     

    So I changed the counter to have a Clk, and did all the logic on posedge Clk like so:

     

    module counter(

      input Clk,

        input b_Up,

        input b_Down,

        input Rst,

      input OE,

        output reg[15:0] count_Out

        );

     

     

    always @(posedge Clk) begin

     

     

       if(Rst == 1)

      count_Out[15:0] <= 16'h0000;

     

      if(b_Up == 1) begin

      if(count_Out[15:0] == 16'hFFFF)

      count_Out[15:0] <= 16'h0000;

      else

      count_Out[15:0] <= count_Out[15:0] + 1'b1;

      end

     

      if(b_Down == 1) begin

      if(count_Out[15:0] == 16'h0000)

      count_Out[15:0] <= 16'hFFFF;

      else

      count_Out[15:0] <= count_Out[15:0] - 1'b1;

      end

     

    end

    endmodule

     

     

    Now I no longer get errors, but I do get a PILE of warnings... Clearly I'm doing something wrong at the hierarchical level, things aren't acting the way I think they are... I'll keep reading and/or wait for expert advice!

     

    I also tried adding the [15:0] to every count_Out as I was getting:

     

    WARNING:Xst:1306 - Output <addr_Out<15:1>> is never assigned.

    WARNING:Xst:1305 - Output <addr_Out<0>> is never assigned. Tied to value 0.

    WARNING:Xst:1290 - Hierarchical block <TestCount> is unconnected in block <main>.

       It will be removed from the design.

    WARNING:Xst:2677 - Node <TestCount/count_Out_15> of sequential type is unconnected in block <main>.

     

    Oh man... transitioning to Verilog is harder than I thought. Gotta love it though, at least I'm learning a lot, and fast!

    Thanks for a third time John! Hope I'm not driving you crazy.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • michaelkellett
    0 michaelkellett over 11 years ago in reply to johnbeetem

    @ Alexander - good advice from John - I'm going to add some lateral comments.

     

    I haven't used Xilinx tools for years having moved to Lattice (mainly because I see them as being long term interested in low cost FPGAs and smaller users) - Lattice do have quite a few low cost (and low power) parts in resaonable packages (and some really nice low power parts in difficult-to-use-at-home BGA packages.)

    The Lattice toolset includes Aldec HDL with a nice block diagram editor which takes care of all the awful tedium of connecting inputs and outputs of blocks.

     

    Finally - before you invest too much time in Verilog at least take a look at VHDL - I won't say that one is better than the other but I certainly find that VHDL suits my way of working far better than Verilog does. (I think John finds the opposite image)

     

    MK

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
  • johnbeetem
    0 johnbeetem over 11 years ago in reply to mraureliusr

    A few things:

     

    1.  Since count_Out is declared "reg" in module "counter", the bus it connects to in the root module should be declared as a wire.  Otherwise you're going through two regs, at least that's how I understand it.

     

    2.  I've never used included "input", "output", and "reg" in a "module" declaration, e.g., module counter(input Clk, input b_Up, input b_Down, input Rst, input OE, output reg[15:0] count_Out);  I've always listed the I/Os on separate lines, like the examples at Wikipedia's Verilog page: http://en.wikipedia.org/wiki/Verilog#Example

     

    This is probably because I learned Verilog in 2000 so I pre-date the 2001 and 2005 improvements.

     

    3.  From your warnings, it looks like module main's connections to "counter" aren't compatible, so XST is tossing everything away.  Make sure the connections are in the correct order and that directions and bus widths are compatible.

     

    4.  Follow the correct template for registers.  These are cleverly hidden in ISE.  In ISE 12.4, go to the Edit menu and select Language Templates.  Then click your way down the hierarchy to Synthesis Constructs / Always / Posedge Clocked and ISE shows you the templates for various types of flip-flops and latches, all of which can be multiple bit.  For example, here's a positive edge-triggered register with active-high async reset and active-high clock enable:

     

    always @(posedge <clock> or posedge <reset>)

          if (<reset>) begin

             <signal> <= 0;

          end else if (<clock_enable>) begin

             <signal> <= <clocked_value>;

          end

     

    If you follow this template, XST will recognize that you want that kind of register and generate the correct logic.  This is how I design with Verilog: I imagine the logic I want, and then write the code that XST recognizes for generating that logic.  It's very much like the early days of C compilers when you could get much better code if you first imagined the assembly language and then wrote code that would help the compiler get there.

     

    In your case, I think your Rst is confusing XST since it's not following the if-then-else structure of the template.

     

    5.  There's no need to specify count_Out[15:0] each time.  If you say count_Out by itself, it's the whole 16-bit register.

     

    6.  If you increment the value of count_Out, you don't need to worry about wrapping the value.  Just write count_Out+1 and it will produce a 17-bit value, which if you assign back to count_Out XST will drop the carry out.

     

    7.  Now that you have a common clock, here's an easy way to update the up/down counter:

     

    count_Out <= count_Out + b_Up - b_Down;

     

    So now you can do the async reset and counter update like this:

     

    always @(posedge Clk or posedge Rst)

      if (Rst) count_Out <= 0;

      else count_Out <= count_Out + b_Up - b_Down;

     

    This is a fine example of how Verilog can create compact source code.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Reject Answer
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube