Wednesday, October 15, 2014

Wednesday Night Hack #6 - Verilog Code Generation using Python and Mako

I spent some time this evening playing with Python and Mako for the purposes of Verilog code generation.  The combination of tools is pretty sweet if you ask me.  Here is a worked out example for a parameterizable barrel shifter.

Mako template:

import math
def log2(x): return int(math.log(x, 2))
def e(x): return eval(str(x))
module bshift_w${w} (
  input [${e(w-1)}:0] in,
  input [${e(log2(w)-1)}:0] shift,
  output reg [${e(w-1)}:0] out

% for i in range(1, w):

  wire [${e(w-1)}:0] out_${i} = {in[${e(w-i-1)}:0], in[${e(w-1)}:${e(w-i)}]};
% endfor

  always @* begin

    out = in;
    case (shift)
% for i in range(1, w):
      ${i}: out = out_${i};
% endfor


Verilog output (w=4):

module bshift_w4 (
  input [3:0] in,
  input [1:0] shift,
  output reg [3:0] out

  wire [3:0] out_1 = {in[2:0], in[3:3]};
  wire [3:0] out_2 = {in[1:0], in[3:2]};
  wire [3:0] out_3 = {in[0:0], in[3:1]};

  always @* begin
    out = in;
    case (shift)
      1: out = out_1;
      2: out = out_2;
      3: out = out_3;


Wednesday, September 17, 2014

Wednesday Night Hack #5 - Update

Life happened.  We bought a house in Silicon Valley.  Work ramped up, code freeze and verification complete of next generation Adreno GPU is on the horizon (being careful to be intentionally vague here).  Thoroughly enjoyed the end of summer by camping and even attended my first personal development workshop weekend.

Last week, I checked in some code to my GIT repository  I released an updated version of my build and run flow (barf) and associated workspace generator (wsgen).  An example BARF script has also been released: analyze.barf.  At the moment, I am not motivated to document the operation of the code or describe any use cases.  The main reason for this is because I do not know the right forum to publish the work (blog, conference paper/presentation, YouTube, etc.).  In any case, these small pet projects are about having fun, no rush ...

Tuesday, July 15, 2014

Post-Vacation Update

It seems I have not posted in about 1 month.  We are in a critical phase of the project at work and my evenings have largely been consumed by my day-job responsibilities.  I also took some vacation.

Since the last post, I have been playing around with a few ideas.  No concrete idea for my pet project yet.  I also read the two books I wrote about here, I have also re-opened The Developer's Code - What Real Programmers Do.  Great book, highly recommended.  The author does an outstanding job of condensing years of experience and wisdom into 50 small essays about software development.

Essay 17 in that book struck a chord with me.  The essay is titled: "Just Say "No" to the Pet Project".  Here's a great quote from is: "Pet project fail when there are no time constraints and nothing is on the line if we don't succeed".  Certainly food for thought...

One idea I had was to revisit buildroot scripts to generate an embedded Linux system and run the system on my MIPS CPU design.  I was almost successful with this years ago, but dropped the idea because it wasn't a needed for the work I was doing at the time.  I am interested in seeing how the scripts have evolved over the years.  I did try running the buildroot scripts running on Cygwin but faced issues.  I could have used a Linux virtual machine, but instead went ahead and bought some parts to put together an inexpensive Linux box / home file server.  The parts should be arriving later this week.

More later ...

Wednesday, June 18, 2014

BARF on BitBucket

I created a GIT repository on for BARF.  I've committed the initial version of the flow and an example script.  Please contact me if there are questions.  More later.

Wednesday Night Hack #4 - Commentary on SystemVerilog-Design Interface Example

I did not get around to synthesizing the example in Chapter 10 of Sutherland's book (refer to my previous post).  Instead, I have some comments about the published example. Most of my time tonight was spent preparing BARF for release.

To keep this post concise, I won't post snippets.  A copy of the source code can be found here.

Comment #1 : Modports TopReceive and CoreReceive are duplicated in interface Utopia.  I don't understand the decision to duplicate the modports.  The SVTB interface should describe the Utopia interface.  The Utopia interface is a set of signals and those signals can either be seen from point-of-view of receiver or transmitter.

Comment #2: The author made an interesting decision to model the register file using interface LookupTable.  I understand what he's trying to do -- DNR, do not repeat (yourself).  His control logic calls a function to read or write a memory array.  The function and memory array live in the interface rather than the module.  If you expect the synthesis tool to infer memories from RTL code, then it's a viable option.  If you need the ability to manually instantiate library cells for memory, then it's not so viable - you cannot instantiate modules within an interface.  I am somewhat weary about the approach for the following reason.  Yes, you can start with synthesis-inferred memory arrays, but what happens when/if you need to move to custom cells?  Then, the interface may not be able to serve its original purpose.

Comment #3: Why didn't author have the main FSM use signals in interfaces rather than drive temporary signals which are then assigned to the interface nets.

bit [0:NumTx-1] Txvalid; // FSM 'drives' this

for (TxIter=0; TxIter<NumTx; TxIter+=1) begin: GenTx
  assign Tx[TxIter].valid = Txvalid[TxIter] // assign to ifc

Comment #4: Combined blocking and non-blocking assignment in rx_valid_state

This example is all kinds of confusing.  I had to turn to StackOverflow to understand what was going on and I'm still not entirely clear how exactly that RTL code gets translated into gates.  The logic basically says to rotate the the round-robin pointer until one of the receivers has a valid cell that is ready to be processed.  Then, the cell is latched and the FSM advances to the next state.  It's an interesting strategy that I assume works because of SystemVerilog's always_ff.

Comment #5: What did I learn about networking?

Not much.  That ATM is a very old protocol.  That ATM is has nearly 10% "cell tax", meaning the header makes up that much of the total size of the cell.  The purpose of the design is to take in incoming ATM cells and arbitrate among receivers.  After a receiver is selected, the register file is accessed update the to-be-transmitted cell's VPI and compute it's new header error control (HEC) value.  Finally, there are two state machine that receive and transmit the cells according to Utopia protocol.