Trying to debug my design for an Audio DAC Cirrus Logic CS4334
J68 is now booting from User Flash Memory on the BEMICRO MAX10 FPGA board
Still debugging the attachment of User Flash Memory to the J68….
LCD Test image and pixel-level detail
Reverse engineering the LCD interface
J68 boots VUBUG monitor on the BEMICRO MAX 10 FPGA board
Working on the User Flash Memory
Launch of HOPE Badge Computer project
Minor problems on techtravels.org email
My Custom HP Logic Analyzer 16700A Cart

Trying to debug my design for an Audio DAC Cirrus Logic CS4334

I purchased a CS4334 to eventually use as an Audio DAC for the badge computer. I’ve never worked with DACs before, and my knowledge of audio is somewhat limited.

This audio DAC is a Cirrus Logic CS4334 with datasheet available here.

This chip is the I2S variant, specifically not the LEFT justified or RIGHT justified one. Each variant has slightly different timing requirements. The I2S specification is located here.

The audio data is a simple 700hz tone for 4 seconds with sample rate of 8000hz, and using signed 8-bit export. The audio file is here. 8k_signed8bit_straight700hz4s <— rename the .txt to .aiff. Use “Import Raw” feature of audacity, specify 8000 sample rate, signed 8-bit pcm. I generate an altera .mif using srecord, and here’s the resulting .MIF —–> 8ksigned_700_4s.

Here’s the output that I’m hearing. There are (8) chunks of sound as far as I can tell.

There IS my 700hz sample found in one of those eight chunks. It’s the “purest” sounding chunk of sound. You’ll know it as soon as you hear. LINK if the player below doesn’t work for you.

Any help to what the heck I’m doing wrong here would be appreciated!!

Here’s my verilog:

dac_clocks dac_clocks_inst (
.areset ( 1'b0 ),
.inclk0 ( SYS_CLK ),
.c0 ( SCLK ),
.c1 ( LRCLK ),
.c2 ( MCLK ),
.locked ( USER_LED[1] )

reg [7:0] sendbyte;
wire [7:0] romout;
reg [13:0] address;

reg SDATA;
wire SCLK; //128khz
wire MCLK; //1.024mhz
wire LRCLK; //8000hz to match the sample rate

assign PMOD_B[0] = SDATA;
assign PMOD_B[1] = SCLK;
assign PMOD_B[2] = LRCLK;
assign PMOD_B[3] = MCLK;

//setup the edge detection for LRCLK

always @(posedge MCLK)

assign LRCLKfalledge=LRCLK_OLD & !LRCLK;
assign LRCLKriseedge=!LRCLK_OLD & LRCLK;

dacrom dacrom_inst (
.address ( address ),
.clock ( MCLK ),
.q ( romout )

/*this is to satisfy "In I2S mode, the MSB of the left channel is valid on the second rising
edge of BCLK[my SCLK] after the falling edge of LRCLK. Similarly, the MSB of the right channel is valid on the
second rising edge of BCLK after the rising edge of LRCLK"

reg [7:0] twocycledelay;
always @(posedge LRCLKfalledge or negedge SCLK)
if (LRCLKfalledge) twocycledelay <= 8'b0;

if (!SCLK) begin
twocycledelay <= twocycledelay + 8'b1;

if (twocycledelay == 8'd2) begin

sendbyte <= romout;
//counter <= 3'b0; //reset the bitcounter because we have a new byte

//else counter <= counter + 3'b1; //send next bit if we're not resetting



always@(posedge LRCLKfalledge) //when it's true that there's a falling edge, read the next byte
address <= address + 14'b1;
if (address == 14'd32000) address <= 14'b0; //data in rom is 32000 bytes deep

reg [2:0] counter;

//send data MSB first. is it already two's complement from audacity?
always@(negedge SCLK) //put the data on the falling edge so that the receiver can read it on rising.

SDATA <= sendbyte[3'd7-counter];
counter <= counter + 3'b1;

J68 is now booting from User Flash Memory on the BEMICRO MAX10 FPGA board

I’ve been struggling for quite a few nights and weekends over the last month or so.

I’ve now successfully attached the J68 to the built-in User Flash Memory. This means that the 16KB (actually about ~13KB) of the ROM monitor VUBUG is now out of the pre-initialized m9k’s configured as a ROM, and now into FLASH. Which is non-volatile, and will survive a reboot. The most important part of this is that it frees up our valuable high-speed on-chip m9k’s.

The solution involved waiting for rd_ena (read enable) to go high, and combining that with the address that makes it a ROM READ, and then passing that to the Altera IP Flash avalon-mm bus interface. Since the latency is a fixed-cycle delay, then I just shift that read-enable pulse to become the “data is ready pulse”, aka data_ack and feed that back to the J68.

I had some more complicated solutions including a state machine, but this way is clearly superior. I had created some bolt-on hardware to help troubleshoot the problem. While it helped initially, when I had the problem fixed, some symptoms in the add-on hardware hid the fact that it was actually working….

The SDRAM controller works in simulation when connected to the J68, and hopefully will be tested on hardware very soon. This puts the ROM code in FLASH, and the RAM on the 8MB memory chip where it belongs. This will give us what we need for future development, including the GPU!

Still debugging the attachment of User Flash Memory to the J68….

So if I take my working UFM avalon-mm Master controller (which if you recall, connects to the Altera Flash Memory IP core), and attempt to attach it to the J68, the J68 no longer boots the ROM monitor code.

Since it’s not booting, I really don’t have many indications as to why. I decided that writing a ROM bus sniffer that records ROM memory requests and responses, including how long it took to satisfy that request, was worth the trouble.

In the image below, you’ll see four 32-bit columns of data on the left. Each row is a separate request.

They are:

  • A 32-bit counter that increments once a master clock cycle. Right now, I’m just running at 33.333mhz, but this J68 works upwards to 100mhz. This is recorded at the time of the request — at the time rd_ena goes high.
  • The ROM memory address being requested (first column on the left in BLUE)
  • The 32-bit counter at the time data_ack goes high, which means the request has been handled
  • The actual 16-bit data value. Ignore the 0xFAFA — that’s just padding. (rightmost column in BLUE)


Note that the requests are being handled the next clock cycle, right now, with the M9k’s serving up the ROM file. So you see 0x3A request, 0x3B response. 0x40 request, 0x41 response, and so on. The flash will not be as quick, and there should be something like (5) cycles between them.

My plan is to attach my newly working debugger to the new J68 solution with the UFM, and compare it. I think the problem will be obvious once I see what is happening…..

LCD Test image and pixel-level detail

So I’ve managed to get a semi-working test pattern image up on the LCD.

Here are a couple shots:


If we zoom in about 10 times, we can see how the LCD really works, on an individual pixel level:


Pretty challenging to get a decent image out of this, but here you can see the individual LEDs that make up the TFT screen that we’re using….. Interesting that the roughly-purple color comes from Blue and Red mixed…. except they aren’t mixed, just very close together.

From http://www.inteltronicinc.com/aa_4.asp?nid=10

Here’s an idealized image…..looks pretty similar to mine!


I actually don’t think that the colors above in my test image are right….there seem to be documentation problems for the pinouts on the BEMICROMAX10…….

Reverse engineering the LCD interface

So I was having trouble getting the LCD working initially, so I ended up probing a working HDMI to LCD converter board sold by adafruit. You see, this board was driving my LCD just fine, but my FPGA couldn’t do diddly. So I wanted to see what I was missing.

This proved more difficult because of these 40-pin FPC connectors. Not sure what the pitch is, but it’s really freakin’ close together.

With a lighted magnifier (3x diopter?), and sharp o’scope probe, I was able to isolate individual pins on the 40-pin, long enough to hit the stop button on the scope.


What you see on the screen is (likely) the probing of the HSYNC pin, showing the pulse in between each line. So between pulses, you’d have 800 pixels worth of video data.

I’ll post the LCD and associated required timing specs once I get everything working 100%, but I’m over the hurdles.

Working on the User Flash Memory

So the Altera Max 10 FPGA we’re using has 256kbits of User Flash Memory. This is non-volatile memory that is built into the actual FPGA itself. This means you don’t need any external memory to get the FPGA to boot itself.

You can use the memory in several different combinations, depending on what you want to do. For instance, you can store a couple FPGA configurations (bitstreams that contain data to program the LUTs internally to “make” the hardware). I believe there’s a jumper on the eval board to allow you to select which one it should boot from. Pretty neat — like dual booting. (which is what they actually call it) In this case, using the flash that way is called CFM — configuration flash memory.

You can also use it as UFM, or User Flash Memory, where you store data for your particular application.

Right now, we are booting this badge computer with the J68 softcore with vubug.txt. (see main project page for the link, or google). This ROM Monitor, made in 1988(!!), is currently stored in the m9k’s (RAM blocks of the FPGA) but is taking up a precious 16K bytes of them. We really need these m9k’s for other things, like high-speed storage for other hardware peripherals, like the GPU.

One minor problem that I’ve discovered: the flash memory has pretty high latency. The m9k’s have none — the clock cycle after a read request, the right data is on the line. While never stated directly in any datasheet/manual that I could find, I saw some reference to a 5-cycle latency. I set off to measure this directly to make sure.


The top yellow line, CH1 on my Rigol 1102E, shows the READ request going out to the Avalon-MM (memory mapped) IP Core generated by Quartus II. Using the core is the only way to access the Flash memory.

The bottom line blue line, CH2, shows the Read Data Valid pin coming back from the memory.

As you can see with the measurement cursors, there’s 100ns delay between the request, and the data being on the line. At the current test speed of 50mhz(1/50mhz = 20ns), that’s five clock cycles. Exactly what I thought.

I am pre-initializing the UFM with a MIF file during programming. For this purpose, you need to make sure to program using the .POF file, and NOT the .SOF file, because the SOF doesn’t contain the data required for the programming of the flash. Programming flash takes longer than just writing the FPGA configuration, so that’s how you know it’s “working.”

I wrote a small state machine, along with my UART from a few projects back, that simply copies the contents of FLASH memory out of the serial port at 115.2K.

Here’s a screenshot


The key thing to note here is that only the high-order/MSB byte is being copied out of the port.

The next step for this effort is to attach the J68’s 16-bit wide bus, that is currently attached to the ROM via an m9k, and attach it to the UFM, which is 32-bits wide. There’s a super lossy way to do this, by simply ignoring the other 16-bits, but I hope I have time to do better than that!


Launch of HOPE Badge Computer project

This is the first post of many in this category.

We have a project page giving the general goals of the project, but most of the hands-on action will happen here in the blog posts. For the latest status, reading these real-time blog posts will give you the best understanding.

We welcome feedback and commentary on the project.


My Custom HP Logic Analyzer 16700A Cart

So after looking at the high priced real HP logic analyzer cart that didn’t look that great to me, I decided to build my own incorporating a ton of features that just really makes my life easier. This is optimized for use over cost.

The physical make up

  • It uses solid 2×2 poplar posts as the overall frame. Easily available from Home Depot.
  • The surface is 3/4″ birch veneered plywood. I use this plywood for a bunch of projects. It’s pretty solid stuff, and the birch really looks nice on top.
  • The surface is treated with Polycrylic. Polycrylic resists damage from abrasion, scuffing, chipping, water, alcohol and other common household chemicals. This is nice stuff, but expensive. Nice topcoat.
  • The visible layered plywood sides were wrapped with birch veneer that I ironed on with a clothes iron.
  • The overall dimensions are 24″ Wide, 27″ Deep, 35″ High including the 4″ high Casters.
  • This thing is built like a brick shithouse. Even with the Heavy LA on it, it’s really sturdy.


Labeled Features

  1. The monitor is a 20″ 4:3 Samsung. It was an older one, but that’s exactly what I wanted. I don’t think it will do the 1600×1200 max resolution, but the next one down (1280 x 1024?) It’s connected to an Ergotron(love this company’s stuff) monitor arm so that I can push/pull/adjust/spin/raise the monitor over top of DUT’s.
  2. This is a 115 watts of light DIY flexible task lamp that I built myself out of spare strip LEDs. It uses less than 20 watts of power. Look here if you’d like to see the full design for it. It works very nicely.
  3. The static dissipative naprene rubber mat from 3M 8831 is beautiful. It’s a great tough surface that really works. I have a wrist-strap (w/ 1M resistor) attached to the corner. The mat is fully grounded through the power strip on the rear.
  4. This custom sliding keyboard shelf is almost 20″ wide and includes a Cherry ML4100 keyboard that is compatible with the LA. I also added a Kensington trackball M01082 which is much more practical given the space limitations. I like this solution better than trying to jam a full-sized keyboard in there. The shelf was put at an ergonomic height.
  5. This is the HP LA itself. Right now, it’s outfitted with a 16752A, (2) 16715A’s, (2) 16717A’s.
  6. I found a generic storage bin that really fit the space underneath the cart. Perfect dimensions. I use it for storing cables, CDs, manuals, and everything related. Nice to have it all in one place.
  7. These are 4″ Black 4″ Black locking Polyolefin Wheels, model L3PB4X. Support up to 250 pounds. I originally used 2″ casters, these are so much better.

Other things that are nice to have

  • A 12-outlet Belkin Surge Suppressor with a 10-foot cord. This is nice because everything attaches to the strip which is zip-tied to the frame, and then just one cord leaves the cart to the outlet. This means I can wheel this thing around my make-shift lab and have it exactly where I want with minimal mess.
  • A wireless bridge that connects the wired RJ45 network port to 802.11 wifi. The brand is IOGEAR, and it simply does the job beautifully. This prevents me from running an ethernet cable over to the LA.