Potting Bench

| Comments

Homemade potting bench, using 15 2.4M Fence boards (£45).

Note for ease of building the height was 1.2M, half a 2.4 meter board, this is too high.

Matlab: Linear Progressions

| Comments

Progressions can be created using the Colon operator

min   = 10
max   = 100
steps = 20

step_size = (max-min)/steps

i = min:step_size:max

Alternatively linspace can be used:

min   = 10
max   = 100
steps = 20

i = linspace(min,max,steps)

This also allows for easily switching to a log scale using logspace.

Matlab: Functions Inputs Parsed Based on Outputs

| Comments

It is quite common to detect how many input arguments have been passed to a function, using nargin (N arguments in). Commonly used to set defaults for arguments not specified.

function result = fun_name(a,b,c);
  if nargin <1
    error('a must be supplied');
  if nargin <2
    b = 1; 
  if nargin <3
    c = 1;

  % ...

However I just discovered nargout (N arguments out(.

This allows the scripts to differentiate between:

x     = fun(a)
[x,y] = fun(a)

Example 1:

function [ varargout ] = nargout_test( input_args )
  disp(['nargout : ', num2str(nargout)])

  % Set outputs
  for i=1:nargout
    varargout{i} = 0;

Example 2, changing input args usage based on number of outputs: note the input keyword change to the input arguments varargin Variable argument in.

function [ varargout ] = nargout_test( varargin )
  disp(['nargin : ', num2str(nargin)])
  disp(['nargout : ', num2str(nargout)])

  if nargout > 2
    error('Too many output arguments')

  if nargout == 1
    % single output first input means something
    varargout{1} = varargin{1};

  if nargout == 2
    % two outputs first input means some thing else
    varargout{1} = varargin{1} / varargin{2};
    varargout{2} = varargin{1} * varargin{2};


A good example is the dcblock script by J M De Freitas.

Which has this syntax:

% SYNTAX    [a] = dcblock(Fc);  
%           [a] = dcblock(fc,fs);  
%           [aQ] = dcblock(fc,fs,B);  
%           [Fc,fc] = dcblock(a,fs);  
%           dcblock(Fc)  
%           dcblock(fc,fs)  
%           dcblock(fc,fs,B)  

SystemVerilog: RTL Types

| Comments

reg and wire were the original synthesisable types. Wires are constantly assigned and regs are evaluated at particular points, the advantage here is for the simulator to make optimisations.

wire w_data;
assign w_data = y;

// Same function as above using reg
reg r_data;
always @* 
  r_data = y ;

A common mistake when learning Verilog is to assume the reg type implies a register in hardware. The earlier optimisation for the simulator can be done through the context of its usage.

This introduces logic which can be used in place of wire and reg.

logic  w_data;
assign w_data = y;

// Same function as above using reg
logic r_data;
always @* 
  r_data = y ;

The type bit and byte have also been created that can only hold 2 states 0 or 1 no x or z. byte implies bit [7:0]. Using these types offers a small speed improvement but I would recommend not using them in RTL as your verification may miss uninitialized values or critical resets.

The usage of bit and byte would be more common in testbench components, but can lead to issues in case of having to drive x’s to stimulate data corruption and recovery.


At the time of writing I was under the impression that logic could not be used for tristate, I am unable to find the original paper that I based this on. Until further updates, comments or edits, I revoke my assertion that logic can not be used to create tri-state lines.

The tri type has been added, for explicitly defining a tri-state line. It is based on the properties of a wire, logic is based on the properties of a reg.

tri t_data;
assign t_data = (drive) ? y : 1'bz ;

If you no longer have to support backwards compatibility Verilog then I would recommend switching to using logic and tri. Using logic aids re-factoring and and tri reflects the design intent of a tristate line.

Originally posted as a SO answer.

Verilog: Define if Not Defined

| Comments

To set a default define option while allowing it to be overridden from the command line.

`ifndef mode_sel
  `define mode_sel 0

The command line should override testbench defined options but this has proven unreliable.

command line to set value:

irun -define mode_sel=1 ...

Verilog: Shm Waveforms

| Comments

The best practice is to use a tcl file:


database -open waves -shm
probe -create your_top_level -depth all -all -shm -database waves

run with :

irun -access +r -input shm.tcl

Alternatively the following can be added to the simulation:

initial begin
  $shm_open("waves.shm"); $shm_probe("AS");

run with irun -access +r

NB: I have had trouble getting this last version to work, the tcl file method is more reliable.

Verilog Timeformat

| Comments

Time can be displayed during simulation using %t.

$display("%t", $realtime);

Timeformat is used to control the way (%t) this is displayed:

//$timeformat(unit#, prec#, "unit", minwidth);
$timeformat(-3, 2, " ms", 10); // -3 and " ms" give useful display msg
  1. unit is the base that time is to be displayed in, from 0 to -15
  2. precision is the number of decimal points to display.
  3. “unit” is a string appended to the time, such as “ ns”.
  4. minwidth is the minimum number of characters that will be displayed.

    0 = 1 sec -1 = 100 ms -2 = 10 ms -3 = 1 ms -4 = 100 us -5 = 10 us -6 = 1 us -7 = 100 ns -8 = 10 ns -9 = 1 ns -10 = 100 ps -11 = 10 ps -12 = 1 ps -13 = 100 fs -14 = 10 fs -15 = 1 fs