Version Control for VHDL Project


A

AndreasWallner

Hi,

I've worked on a few tiny VHDL projects in the past and since I have
to write a bigger project for my university, I wanted to ask how you
guys use source control on projects using multiple libraries.

I know how to use version control in general, the question is how to
work with those libraries. For example: Consider a design using some
sort of softcore processor and peripheral modules for that processor.
I would make a seperate library for each module as well as for the
processor itself. This way the modules itself could be reused. In that
case I would also use a different repository for each module (We use
Subversion and Git for Version control).

If I would do it that way, I would have a problem taging a specific
revision (for example the first version delivered to the client). Do
you use tags? Do you use SVN/Git externals/submodules? Do you
structurize you code in a way to make is neccesary to use more than
one "level" of libraries in you projects? (For example a Design using
an AES core itself using a librarie providing the S-Box for AES
(shared by AES and DES))?

I would really appreciate information how you handle multiple
libraries, because each scenario we thought of seems to be flawed in
some way.

The second reason I ask this is: While I do study electronics, I'm
also very much into programming. Because I that, a colleague and I
started working on a program to edit VHDL/Verilog Code, much like HDL
Designer from Mentor. (Yes we know this is a lot of work, and yes we
have done project in a reasonable size before to know what awaits us).
Although It is not ready to be tested in a real world situation, I was
interested how you handle such version control issues, so we might be
able to incorporate such functionality. (At the moment the only thing
it can do is managing various libraries and open VHDL files to edit
them)

I hope I have explained myself clear and not missed a note regarding
that issue in my search on the list.

Regards,
Andreas
 
Ad

Advertisements

M

Mike Treseler

AndreasWallner said:
I've worked on a few tiny VHDL projects in the past and since I have
to write a bigger project for my university, I wanted to ask how you
guys use source control on projects using multiple libraries.

I prefer multiple packages, but one library (work) to
simplify the sources and be compatible with
vhdl-mode makefiles.
The second reason I ask this is: While I do study electronics, I'm
also very much into programming. Because I that, a colleague and I
started working on a program to edit VHDL/Verilog Code, much like HDL
Designer from Mentor.

Have a look at vhdl-mode first.

-- Mike Treseler
 
A

AndreasWallner

I prefer multiple packages, but one library (work) to
simplify the sources and be compatible with
vhdl-mode makefiles.

Ok, I think we misunderstood each other. Thats because I did not mean
library in the sense of an VHDL Library (like work or ieee), but
library in the sense of a module providing some sort of functionality.
(So more in the sense of a normal software library). Excuse me, but
that's the way HDL Designer uses the term library too...while writing
I forgot it could be misleading.

The question I had in mind was really more: How do you manage to track
the state of self written IP Cores and the top level project with your
version tracking system. Espacially if you want to tag the whole
project, how do you ensure the correct version of the used IP cores is
used.

I hope that cleared our misunderstanding.
Have a look at vhdl-mode first.
I know vhdl-mode and it is somehow great...but it's not as much fun as
writing your own piece of software (everybody has to have a
hobby ;-) )

Regards,
Andreas
 
M

Mike Treseler

AndreasWallner said:
The question I had in mind was really more: How do you manage to track
the state of self written IP Cores and the top level project with your
version tracking system. Especially if you want to tag the whole
project, how do you ensure the correct version of the used IP cores is
used.

There's little difference between tags and branches in Subversion.
Both are directories that are created by a copy.
If I don't commit changes, it stays a tag or "snapshot".
If I commit a change, it becomes a branch.

I know vhdl-mode and it is somehow great...but it's not as much fun as
writing your own piece of software (everybody has to have a
hobby ;-) )

Go for it.
But vhdl-mode sets the bar high.

-- Mike Treseler
 
K

KJ

Mike Treseler said:
There's little difference between tags and branches in Subversion.
Both are directories that are created by a copy.
If I don't commit changes, it stays a tag or "snapshot".
If I commit a change, it becomes a branch.

I think what Adreas is asking about has to do with reusable (or potentially)
reusable IP. You create some widget and put it into a Subversion (or other)
repository. Sometime later you're working on a *new* design that happens to
need the same widget. There are a couple ways to go about getting the old
IP

1. Copy/replicate. Export the IP you need into the folder for the new
design. Then when you check in the new design into its repository it's
archived. The drawback here is the usual thing that happens with
copy/paste, you've created a totally new widget that begins life exactly the
same as the first widget, but they can each evolve down different paths if
you find out later that you'd like to update the widget (in fact there is no
'the widget' anymore, there are 'two widgets', then three, four, more).

2. Have the new design reference widget. In Subversion you do this via the
'svn_external', the potential problem here is that the only way to totally
lock down exactly what you're getting for widget is to specify the revision
to pull when you reference the widget. This is OK if widget is firm and
solid, but a pain if widget is also undergoing development and you're still
in the development phase of your new thing that uses widget and you'd like
to get 'latest/greatest'. The pain then becomes at the end when you're
trying to exit that mode, going back into each of those svn_externals to
then specify the revision you want is a manual, prone to problems effort.
If you don't do this, then when you try to check out/export an archived
design your references to widget will pull the 'head' revision, not the
revision that existed at the time you wanted to archive.

3. Have the new design reference the new widget as in #2. But when you get
to the point of releasing something and want to be able to create a tag that
you can use as a real archive so that you go back and pull the design as it
really existed at some prior time, but still have the benefits of
referencing a single widget design when you're in development mode, then you
need to use 'svncopy.pl'
(http://svn.collab.net/repos/svn/trunk/contrib/client-side/svncopy/svncopy.README).

This is one particular area of source control where MS Source Safe beats
Subversion hands down. The fact that you can't reference a widget in some
repository and be able to later tag it down to a specific revision at design
complete without a lot of effort (#2) or having to use scripts to help along
the source control tool's weakness (#3) is a major weakness, 'specially
considering that this is after all a source control tool.

Kevin Jennings
 
M

Mike Treseler

AndreasWallner said:
The question I had in mind was really more: How do you manage to track
the state of self written IP Cores and the top level project with your
version tracking system. Especially if you want to tag the whole
project, how do you ensure the correct version of the used IP cores is
used.

This is similar to the problem of two developers working on the same
module at the same time. Sometimes there are conflicts that have to be
manually merged.

I prefer KJ's "copy/replicate" method. My top priority is
to get the project finished. I can merge back changes to reusable
modules when the pressure is off.

-- Mike Treseler
 
Ad

Advertisements

C

Charles Gardiner

I have been using subversion for this purpose for maybe three years now.
I have a number of reusable cores (varieties of Timers, Uarts,
wishbone-to-whatever adapters, dma controllers etc.) and link them into
a customer project as required by simply setting subversion externals.
Each 'core' is developed as a project on it's own.

Essentially, I have a repository for my reusable stuff, a different
repository for customer projects and so on.

I think one of the most important parts is a suitable directory
structure. If you design things regularily enough, it's not much of a
problem to include a core as part of another core and to include the
super-core as part of a customer project.
 
A

AndreasWallner

I have been using subversion for this purpose for maybe three years now.
I have a number of reusable cores (varieties of Timers, Uarts,
wishbone-to-whatever adapters, dma controllers etc.) and link them into
a customer project as required by simply setting subversion externals.
Each 'core' is developed as a project on it's own.

Essentially, I have a repository for my reusable stuff, a different
repository for customer projects and so on.

Do you use a single repository for all your reusable stuff? With
subfolders for each IP?
I think one of the most important parts is a suitable directory
structure. If you design things regularily enough, it's not much of a
problem to include a core as part of another core and to include the
super-core as part of a customer project.

Would you mind telling me about the folder structure you use?
 
A

AndreasWallner

Excuse the duplicate answer, but I used the wrong button the answer
the first time...
I think what Adreas is asking about has to do with reusable (or potentially)
reusable IP.  You create some widget and put it into a Subversion (or other)
repository.  Sometime later you're working on a *new* design that happens to
need the same widget.  There are a couple ways to go about getting the old
IP

You are right on that point. Excuse me for not being clear here.
1. Copy/replicate.

We thought about that, but bringing the changes made to an core back
into the main repository is the hard part here, as you pointed out.
2. Have the new design reference widget.

Thanks for that information, I'll look into that subversion feature.
I didn't know svn provides that functionality.
(I never needed to use something like that on my previous projects
(especially since I do software projects (C/C++) most of the time,
there we mostly install the needed libraries to system paths, which is
not quite applicable for VHDL projects)
3. Have the new design reference the new widget as in #2.  But when you get
to the point of releasing something and want to be able to create a tag that
you can use as a real archive...

I think you should really have a look at git, it is really easy to use
(after you have understood the differences from DVCS to traditional
VCSs ;-)) and provides a feature called 'submodule' which is excatly
what you described. If you create a tag, the content of the whole
project is saved, and since a submodule not only contains the location
of the imported repository, but also the precise commit currently
used, the state of the IP cores is also preserved
 
A

AndreasWallner

I prefer KJ's "copy/replicate" method. My top priority is
to get the project finished. I can merge back changes to reusable
modules when the pressure is off.

Since we are a university time is not a pressure (most of the time).
The bigger problem would be if people forget to push their changes
back into the IP core repository. If you have a disciplined
development team, or are developing alone I can imagine that this
would not be a problem, but my environment that could lead to serious
problem.

Like someone chaging an IP core, but introducing a bug, fixing that
bug in the project repository, but forgetting to push the changes into
the IP repo.

Other than that we would also loose the information who did specific
changes, and why...
 
K

KJ

Essentially, I have a repository for my reusable stuff, a different
repository for customer projects and so on.

What method do you use to lock down the revision of the subversion external
references within the customer repository (for archival purposes) but still
allow the latest/greatest revision to be used for development (or future
customer enhancements)? svncopy.pl? Manually? Something else?

KJ
 
Ad

Advertisements

C

Charles Gardiner

AndreasWallner said:
Do you use a single repository for all your reusable stuff? With
subfolders for each IP?

Exactly, I use a single repository for the reusable stuff with each
having it's own substructure
Would you mind telling me about the folder structure you use?

No Problem. This is only my suggestion, though. I'm sure at least 100
others will also work. I think the important thing is a structure that
is regular, reproducable and scalable but still flexible.

My (ASIC/FPGA) Project structure looks like this (not all line-breaks
are intentional). BTW, each reusable unit also has a similar structure.

design doc flow image impl reports resources scripts verify work

Sometimes there is a 'driver' directory here too.
From a chip perspective, design and impl are the important ones. 'impl'
contains target-specific stuff like PLLs, Memories etc. Often generated
by perl or tcl scripts in tool-related directories below 'scripts'

'design' has the further subdirectories
common top units

Under 'common', I have things like my utility libraries and frequently
used smaller blocks such as say FIFO controllers. (Yes, I prefer to roll
my own). These nearly all come from the reusable repository.

'top' usually just contains a core and top-level pin-out block. i.e. the
core is the only thing instanced in the 'top' block along with any
additional polarity inversions, tri-state etc.

The most interesting is the 'units' tree. This is a mix of
project-specific and reusable cores. Each unit can have it's own top
and/or units subdirectories depending on complexity. Often, there is
just a directory called 'verilog' or 'vhdl' directly under a unit,
containing the source code for that unit.

Looking at one of my current designs, the following as an excerpt from
below the <project_name>/design/units path:
credit_config lscc_pcie_wb01 wb_spi_ad7490_c32

Here, the first and last are project-specific, the middle one is from
the reusable repository and is a wishbone adapter for the Lattice PCIe
core. Running 'svn propget svn:externals' on this (middle one) gives:

lscc_pcie_wb01 -
top http://regulus/svn/SoC/lscc_pcie_wb01/trunk/design/top
units http://regulus/svn/SoC/lscc_pcie_wb01/trunk/design/units

So, the project-local dirs
<design_name>/design/units/lscc_pcie_wb01/top and
<design_name>/design/units/lscc_pcie_wb01/units are imported from the
reusable-stuff repository.

There is also a directory tree
<design_name>/design/units/lscc_pcie_wb01/config which is local to the
design and just contains a package taking care of some project-specific
configurations, but which is required by the files from the repository
(this is an example of what I mean above by flexible. A directory tree
that basically stradles the reusable and project repositories)

The test-bench resides below the 'verify' path and is very similar to
the directory structure below 'design'. Depending on the design, there
can be various BFMs etc. Reusable test-bench stuff gets hooked in here
the same way as above.

Beside all this, I have a collection of perl/java scripts for generating
make-files, testbench skeletons etc. which of course are designed to
work with this structure.

As I said, just look on this as food for thought. You may have other
requirements.

Best of luck with your projects.
 
C

Charles Gardiner

KJ schrieb:

What method do you use to lock down the revision of the subversion external
references within the customer repository (for archival purposes) but still
allow the latest/greatest revision to be used for development (or future
customer enhancements)? svncopy.pl? Manually? Something else?

KJ

I followed the subversion suggestions here. Each reusable unit (and of
course each customer project) has a tags, branches and trunk
subdirectory. Every project release to a customer is tagged (svn copy)
and the output of 'svn -R propget svn:externals .' documented just for
safety. Every version of a reusable unit included in a customer project
is also taken from an entry under //<svn_server>/SoC/<reuse_block>/tags
and never directly from the trunk

Continued development, fixes etc. to a resuable core are done as a
project on it's own (under trunk). If a customer gets an upgraded/fixed
version, I generally just remove the previous sub-tree to the reusable
block in his project and modify the svn:externals to pick up a new
tagged version.

Unfortunately, I'm currently running subversion Version 1.4.4. According
to my understanding, the newest releases give much better merging
options but I just don't have time to take my system down for a few days
at the moment. But it's on my task-list.
 
K

KJ

Charles Gardiner said:
KJ schrieb:



I followed the subversion suggestions here. Each reusable unit (and of
course each customer project) has a tags, branches and trunk
subdirectory. Every project release to a customer is tagged (svn copy)
and the output of 'svn -R propget svn:externals .' documented just for
safety.

Creating tags using 'svn copy' though doesn't lock down the revision of
externals when creating the tag so when you go back later to get the tag and
check it out, anything from an 'svn_external' will return the 'head'
revision of the referenced folder, not the revision that existed at the time
that you created the tag...good thing you have the 'svn -R propget
svn:externals .' documented so you know which revision was really used at
the time the tag was created.

Kevin Jennings
 
A

AndreasWallner

Thank you two for taking the time to explain your approaches to me,
I'm really grateful.
I think we will try using the approach Charles presented, but we'll
stick with git as a version tracker.

I don't want to advertise git here, but you should really have a look
at it, as it provides exactly the functionality Kevin was missing from
this idea. (Tagging through all external imports)

Andreas Wallner

PS: Would you use an editor which forced you to use git?
 
A

AndreasWallner

I also had a look at the other two big DVCS's, those too have such a
feature (Mercurial calls them Nested Repositories, Bazaar Nested
Trees) if you don't like git.

Bazaar can also easily be used as a centralized VCS, that's just a
setting. They might be worth a look, especially for this issue.
 
Ad

Advertisements

M

Mike Treseler

AndreasWallner said:
Since we are a university time is not a pressure (most of the time).
The bigger problem would be if people forget to push their changes
back into the IP core repository.

I don't follow.
Version control can't remind a developer to do that.

-- Mike Treseler
 
A

Andy Peters

Creating tags using 'svn copy' though doesn't lock down the revision of
externals when creating the tag so when you go back later to get the tag and
check it out, anything from an 'svn_external' will return the 'head'
revision of the referenced folder, not the revision that existed at the time
that you created the tag...good thing you have the 'svn -R propget
svn:externals .' documented so you know which revision was really used at
the time the tag was created.

Kevin,

I've been using Subversion for FPGA designs for quite awhile now and
I've come up with what I think is a reasonable workflow.

Of course lots of things are reusable, and anything that is so is a
separate project in the repository. As an overview, my repository
structure is as follows:

---------------------------------------------------------------
root\fpga\projects <-- All chip-level designs go here
\projects\A\tags\
\branches\
\trunk\src\ <-- VHDL goes here
\projects\A\trunk\fitter\ <- synthesis/P+R stuff
\projects\A\trunk\testbench\ <- obvious!
\fpga\models <- various simulation models for
testbenches
\fpga\modules <- resuable "cores" go here
\fpga\modules\spimaster\tags\
\branches\
\trunk\src
\trunk\testbench
\pwm\tags\
\branches\
\trunk\src\
\trunk\testbench\

----------------------------------------------------
Now here is how it works. When I'm doing a new FPGA design that needs
an existing module, I always use TAGGED versions of those modules.
This means I put the svn:externals property on the design's src
directory as follows:

spi svn://repo/fpga/modules/spi/tags/spi_v1.0.0/src
pwm svn://repo/fpga/modules/spi/tags/spi_v1.1.0/src

(don't forget the src, otherwise you get the testbench for the module
too!)

Now when you check out the FPGA design, you get the tagged (by
convention, immutable) versions of those modules.

If you are developing a new module along with your FPGA design, still
keep it as a module, but just include the trunk of that module until
you decide that it's ready for "release," at which point you tag it.
Oftentimes I will check out the submodule into its own working copy,
code it up, verify with the testbench, and commit, and only after
that's done will I add it to the externals for the larger design.

If you decide to change a tagged module, change the external to
reference either the trunk of that module, or create a branch of it.
Update the FPGA design's working copy and now you are developing on
the module's trunk. When you are finished and satisfied that the
module works as required, create a new tag, then change the chip
design's src directory's externals to reference the module's new tag.

Basically, then, when you decide to release the whole design, ALL of
the submodules pulled in by svn:externals should be TAGGED versions,
not from their respective trunks. So when you check out your design's
released tagged version you get what you expect, regardless of later
changes to any modules, which I suppose is the whole point of version
control.

I like to add the .bit and .mcs files to my design release tags, too.
Here's what I do. Before you tag your FPGA design for release, check
out a working copy (all tagged submodules!) _from the trunk_ and build
it. When complete, do an svn add on the .bit and .mcs files. (You
might wish to create a separate directory for these files under the
project root, and add that directory instead.) Do NOT commit the
change. Instead, create a tag from the _working copy_ (very easy in
TortoiseSVN). When that's done, your repo has a tagged release version
of the FPGA including .bit and .mcs. The working copy remains on the
Now, do an svn revert on the .bit and .mcs files because there's no
reason the trunk should contain build results.

Anyways, it's actually easier to use than to describe, and it works
for me.

-a
 
A

AndreasWallner

I don't follow.
Version control can't remind a developer to do that.

Yes it can: If a developer needs to copy the changed files back into
another folder and commit his changes into another folder (the
repository of the core) we won't be able to ensure all changes (e.g.
bugfixes) because people are just too lazy to do this, or pretend not
to have time for it. Since they are students like me they can't be
forced, and certainly cannot loose their job or something else because
of such problems.

If we use a system where you have to import IP cores as subtrees like
Kevin suggested, commiting the project results in a commit of the
changes made to the subtree, so the IP core repository is
automatically updated with the changes made in the project
repository.
That's how version control can remind you.

Regards,
Andreas Wallner
 
Ad

Advertisements

M

Mike Treseler

AndreasWallner said:
If we use a system where you have to import IP cores as subtrees like
Kevin suggested, commiting the project results in a commit of the
changes made to the subtree, so the IP core repository is
automatically updated with the changes made in the project
repository.

I hear what you are saying, but this assumes
that all changes are worthy,
or that someone is monitoring
the core repository, fixing testbenches
and scripts to cover the changes as they come in.

-- Mike Treseler
 

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

Top