Skip to content

Latest commit

 

History

History
208 lines (158 loc) · 13.5 KB

0030-2020-06-17.md

File metadata and controls

208 lines (158 loc) · 13.5 KB

17 Jun 2020

test05f

Per https://www.fpga4fun.com/MusicBox3.html I made test05/t05f which is almost exactly the code given in the tutorial.

It also shows how you can XOR vectors of bits together, though.

It works! Just note that what it names each note (i.e. A, B, C, etc.) doesn't match the standard A-440 frequencies.

  • Base frequencies come from a look-up table of base periods that has 9-bit values, with 9'b111111111 (512-1) being the higest variant, and each subsequent value being divided by a factor of 2^(n/12), i.e. such that the 10th semitone (G) has a period of 512/2^(10/12)-1 (or 287-1).
  • This period is then effectively multiplied by the octave counter, which is based on 2 to the power of 3..8.
  • Hence, the lowest octave A note has a duty cycle of length 512256 or 131072, hence a frequency of 25MHz/(1310722), or (I think) 95.37Hz.
  • Likewise, the highest octave A note is 2^5 times higher, i.e. 3051.76Hz?

test05g

Next test makes some minor improvements to test05f and in particular adds a test mode where pressing any combination of the buttons will override the default note counter and sustain a specific octave/note:

L button R button Test Frequency
Open Open None; play normal scale
Open Pressed Octave 3, Note 0 (A) 25MHz/512/32/2 => ~763Hz
Pressed Open Octave 4, Note 0 (A) ~1526Hz
Pressed Pressed Octave 5, Note 0 (A) ~3052Hz

The way I implemented the test mode override -- while still keeping the underlying divide_by_12 note scale counter -- looks a bit messy, but is evidently a correct way to do it without resorting to an extra reg:

  • divide_by_12 module represents hardware that is always there.
  • It wants to put a result on wires all the time, so we give it default_octave and default_note.
  • Our main wires for octave and note are always assigned using a mux approach, represented here using ternary operators. Thus they can select from either preset values, or from default_octave and default_note depending on testmode (which is controlled via the pushbuttons).

As it turns out, if a reg were used in this construct with an always block it wouldn't necessarily actually synthesize to a register, because I think it can work out that direct wiring would be possible:

  • Notice how here the author asserts that the given code examples are equivalent, and therefore that the reg might in fact just be treated as a wire anyway?? I guess this is because of the always @* making the reg sensitive to (and hence constantly changed by) the state of signals a and c, rather than being (say) clocked... in other words, I don't think it actually has a saved state.

Here are some references:

  • Using reg instead of wire and then putting the case in an always block will not infer a flip-flop?
  • It could be done using a case if the case is changed into a function but this doesn't necessarily make us any better off, because we still need the module instantiated somewhere.
  • Is it possible instead to use if or case with single, consistent assignments, like this? Maybe that, again, can only be done when using a reg and aways block; see the next slide, in particular:

    All data types in always blocks must be declared as a ‘reg’ type.

    This is required even if the data type is for combinational logic.

test05h

I tried to adapt test05g so it would use A440 tuning, and I made test05h. I had intended to use a function to calculate period constants for me, but I hit a bug and ended up just hard-coding the constants (at least for now).

I also got fitter errors which I managed to work around (but not sure if it shows my design is poor):

  • Original error:
    Re-checking device resources ...
    Mapping a total of 48 equations into 4 function blocks.......................................................................................
    ERROR:Cpld:892 - Cannot place signal U1/tone<3>. Consider reducing the
    collapsing input limit or the product term limit to prevent the fitter from
    creating high input and/or high product term functions.
    ....ERROR:Cpld:868 - Cannot fit the design into any of the specified devices with
    the selected implementation options.
    
  • Per this, it might be a good idea to check out the CPLD Fitting, Tips and Tricks. I'm not sure whether my design just needs a lot more CPLD space, or whether it just happens to be arranged in a way that causes trouble when the fitter tries to find a solution.
  • I went to "Implement Design" Process Properties and then "Fitting" and changed "Implementation Template" to "Optimize Density" instead of "Balanced".
  • This seems to have worked around the problem. At a glance it looks like it has substantially reduced the various numbers (i.e. percentage of total density), but I can't say from what, exactly.

Now the scale starts at octave 0, note 'A' (actually A2, officially, at 110Hz). The testmode buttons work as they do in test05g, too.

Fit bug

I was getting an error along the lines of this: https://forums.xilinx.com/t5/CPLDs-Archived/FIT-fails-with-no-error-reported/td-p/70945

  • This happened after I had successfully synthesized the design, but warnings clued me in to some errors in the code.
  • I fixed the errors, and it was when trying to synthesize again that it was coming up with "Process "Fit" failed".
  • I did notice that the HTML report was a couple of hours out of date; this might be the reason for the error.
  • I haven't worked out why sometimes the files don't properly rebuild. Maybe it's better to temporarily transfer all the project files into the VM and cross-manage with GitHub.
  • Instead, for now, I've: (a) shut down both VMs; (b) deleted the entire working directory; (c) started both VMs back up again.

The steps above didn't fix the problem. This is what I was seeing in the Console window of ISE:

Started : "Fit".
Running cpldfit...
Command Line: cpldfit -intstyle ise -p xc9572xl-7-VQ64 -ofmt vhdl -optimize speed -htmlrpt -loc on -slew fast -init low -inputs 54 -pterms 25 -unused float -power std -terminate keeper test05f.ngd
WARNING:Cpld - Unable to retrieve the path to the iSE Project Repository. Will
use the default filename of 'test05f.ise'.
.
.
.
Re-checking device resources ...
Mapping a total of 51 equations into 4 function blocks.................
Design test05f has been optimized and fit into device XC9572XL-7-VQ64.

Process "Fit" failed

I tried running the same command via the shell ...

cpldfit -intstyle ise -p xc9572xl-7-VQ64 -ofmt vhdl -optimize speed -htmlrpt -loc on -slew fast -init low -inputs 54 -pterms 25 -unused float -power std -terminate keeper test05f.ngd

...and it segfaulted:

...
Re-checking device resources ...
Mapping a total of 51 equations into 4 function blocks.................
Design test05f has been optimized and fit into device XC9572XL-7-VQ64.
Segmentation fault (core dumped)

The suggestion here is to change the report format from Source to ABEL. To do this we:

  1. Right-click the "Fit" process;
  2. Select "Process Properties...";
  3. Choose the "Reports" tab;
  4. Change -ofmt option to ABEL;
  5. Hit "OK".

Then re-run the process, and it worked for me this time. It then runs these commands as part of the "Fit" process:

# Generate Post-Fit Timing Data
tsim -intstyle ise test05f test05f.nga

# Generate Timing
taengine -intstyle ise -f test05f -w --format html1 -l test05f_html/tim/timing_report.htm

Synthesis parser bug

While working on test05h, I got this error during synthesis:

Analyzing module <music> in library <work>.
INTERNAL_ERROR:Xst:cmain.c:3464:1.56 -  Process will terminate. For technical support on this issue, please open a WebCase with this project attached at http://www.xilinx.com/support.  

Process "Synthesize - XST" failed

It looks like this is described in AR# 51670 (more info here), and apparently the solution for ISE is to:

update the Synthesis Property or Setting with "-use_new_parser yes" in the other command line options

...which I did like this.

...but it didn't work. That gives an error about the option not being suitable for the selected device:

ERROR:Xst:2883 - Option "-use_new_parser" is not available for the selected device family.

I tried running this command directly from the shell:

xst -intstyle ise -ifn "/home/ise/shared_projects/sandpit/fpga/XC9572XL/test05/t05h/working/test05g.xst" -ofn "/home/ise/shared_projects/sandpit/fpga/XC9572XL/test05/t05h/working/test05g.syr"

...but it didn't help:

[ise@localhost working]$ xst -intstyle ise -ifn "/home/ise/shared_projects/sandpit/fpga/XC9572XL/test05/t05h/working/test05g.xst" -ofn "/home/ise/shared_projects/sandpit/fpga/XC9572XL/test05/t05h/working/test05g.syr"
Reading design: test05g.prj

=========================================================================
*                          HDL Compilation                              *
=========================================================================
Compiling verilog file "../div12.v" in library work
Compiling verilog file "../music.v" in library work
Module <divide_by_12> compiled
Compiling verilog file "../test05h.v" in library work
Module <music> compiled
Module <test05g> compiled
No errors in compilation
Analysis of file <"test05g.prj"> succeeded.
.
.
.
=========================================================================
*                            HDL Analysis                               *
=========================================================================
Analyzing top module <test05g>.
Module <test05g> is correct for synthesis.
 
Analyzing module <music> in library <work>.
INTERNAL_ERROR:Xst:cmain.c:3464:1.56 -  Process will terminate. For technical support on this issue, please open a WebCase with this project attached at http://www.xilinx.com/support.  
Aborted (core dumped)

I suspect the problem is with my mathematical expressions.

For now I just hard-coded the constants.

Notes

Next stuff to try

  • Use z values.
  • Based on this, try some sort of test with a reg that is sensitive to everything, and see if it actually synthesizes to different logic than my existing combinations of wires.
  • Likewise, try this, which probably still requires a reg target.
  • Read important stuff about sequential logic.