Verilog newbie with clocking question

I'm a total Verilog newbie, having just started yesterday but already finding it far less intimidating than the VHDL I thought I was going to have to deal with. I'm a systems software programmer with enough hardware knowledge to be dangerous, and a few projects under my belt (microcontroller based servo-style stuff). FWIW I'm not taking any classes on this stuff (yet?), just screwing around on my own.

I'm playing with the design of a multi-channel analog capture system, where I need an FPGA to take a number (4-16) of SPI inputs from stereo audio ADCs, and multiplex them all into a 16-bit bus with a single write strobe, to be connected to a Cypress EZ-USB FX2.

I'm pretty sure I've got almost all the logic in place, *except* for a clocking issue. The PCM audio SPI port includes an LRCLK (left-right clock) that goes high at the end of the left channel sample, then goes low at the end of the right channel sample.

The problem is that even with a lot of googling, I haven't been able to find (or recognize?) a way to create a pulse I can use to start the parallel output sequence, on *both* edges of the LRCLK:

SCLK .. _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_- .. DATA .. xxxxxxRRRRRRRRRRRRxxxxLLLLLLLLLLLLxxxxRRRRRRRRRRRRxx .. LRCLK .. __----------------________________----------------__ .. goal .. __-_______________-_______________-_______________-_ ..

Once I have the LRCLK edge pulse, I can start up the FSM that will drive each group of 16 bits to the output bus one at a time, based either on SCLK or another clock (safer with SCLK, as it stays a basic synchronous design AFAICT).

Any hints would be greatly appreciated, especially code fragments Also if anyone can suggest a good example-heavy, relatively theory-light book on Verilog FPGA design (e.g. "Verilog FPGA Design by Example for Dummies") that I might get...

TIA, Omega aka Erik Walthinsen snipped-for-privacy@temple-baptist.com

Reply to
Erik Walthinsen
Loading thread data ...

(snip)

While its name says CLK, I would consider LRCLK as an enable, which enables the left or right channel shift register as appropriate. You can then use it to enable a latch on the appropriate edge of SCLK. What is the timing relationship between SCLK and LRCLK? (snip)

Imagine you have a large box full of TTL chips and wire, and you want to build something. Now think of verilog as instructions to a robot on how to wire up those chips. If you think of it like software you will get confused easily.

-- glen

Reply to
glen herrmannsfeldt

The chip I'm targetting atm is the PCM1804, with the datasheet at:

formatting link
The waveform is at the very bottom of page 21, and timings follow on the next page.

The first thing to do on receiving an LRCLK edge is to latch from the shift registers, so I have a posedge LATCH wire to each input section. If I have that, I can kick off the FSM shortly thereafter. Basically what I'm trying to figure out is what the verilog looks like that causes the LATCH to go high on both edges of LRCLK, and drop back down some time before the next LRCLK edge (thus probably following an SCLK transition).

Problem is, my logic design skills are really rusty, being mostly limited to what I learned almost a decade ago in the logic part of the CS major in high school. But I've found that Verilog is almost excactly the right mix of software and hardware design styles for me that I cranked out the bulk of the necessary design in a couple of hours, the same day as picking up Verilog for the first time.

Thanx, Omega aka Erik Walthinsen snipped-for-privacy@temple-baptist.com

Reply to
Erik Walthinsen

Well, with a lot of screwing around, I managed to get what I needed. Veteran developers, please observe the barf bag located in the seat-back in front of you:

module edgeclock(clk, lrclk, strobe); input clk, lrclk; output strobe; wire strobe;

reg int_strobe; reg prev_lrclk;

always @(posedge clk) begin if (prev_lrclk != lrclk) int_strobe = 1'b1; else int_strobe = 1'b0; prev_lrclk = lrclk; end

assign strobe = int_strobe; endmodule

In Quartus II Web Edition simulation, this yields a strobe pulse that spans a complete clk cycle, starting at the rising clk edge immediately following a lrclk transition:

clk .. __--__--__--__--__--__--__--__-- .. lrclk .. ____----------------____________ .. strobe .. ______----____________----______ ..

Once that was in place, the state machine (hardly even that) for blasting the various registers out was a piece of cake, and the whole design is functional to a first approximation.

All this in less than 36 hours from first trying my hand at Verilog. Very cool.

Reply to
Erik Walthinsen

A small tip, use non-blocking assignments:

always @(posedge clk) begin if (prev_lrclk != lrclk) int_strobe

Reply to
Jon Beniston

Read below what Ian Lang has written on this subject. -- Mike Treseler

______________________________________________

When must non-blocking assignments be used in RTL code?

Answer: to assign the outputs of any clocked process that is used synchronously within another clocked process. That's it. Any other usage is in fact redundant (and to my mind superfluous). In VHDL, it is in fact impossible not to do this because all communications between processes have to be by means of signals. This document contends that that is the only time that non-blocking (or VHDL signal) assignments should be used. Most designers make much more liberal use of the non-blocking assignment than strictly necessary. I would argue that this obfuscates the code in that the real usage is lost amongst the non-essential uses. The example UART design (RTL.vhd) shows how it is done. The output readData, for example, is generated thus.

The corollary of this rule is that, synchronous outputs aside, all other assignments should be non-blocking (Verilog) or use variables (VHDL). Again, the UART example shows this. It can be seen that the VHDL and Verilog versions of this design are exactly analogous. In fact, this style lends itself to being auto-translated between the two languages.

In general, I would advocate only using non-blocking assignments (VHDL signal assignments) when their special behaviour is actually required. This is at odds with conventional wisdom but in keeping with a minimalist approach whereby code that does nothing and behaviour that isn't required are avoided.

formatting link

Reply to
Mike Treseler

Hi Erik,

I think others have described a solution to your problem.

For a very good book on Verilog (and VHDL), check out "HDL Chip Design" by Douglas J. Smith. It has equivalent Verilog and VHDL for examples, and often equivalent schematics for both. There's more example code in this book than any other I've come across. For example, there's 74 pages solely on FSMs with 13 example state machines. As the title suggests the book details good design practice in general.

I did about 3 years of VHDL before learning Verilog about 1.5 months ago so YMMV on how much Verilog resources you need. This book plus a few Google'd websites taught me as much Verilog as I need. Don't forget to check out

formatting link

- a great summary of the cool Verilog 2001 additions.

-- Pete

Reply to
Peter Sommerfeld

Erik Walthinsen wrote: (snip)

A FF to latch the previous value, an XOR gate to indicate that the current value is different, and another FF to latch the output of the XOR gate.

I might have written it:

int_strobe = prev_lrclk ^ lrclk; prev_lrclk = lrclk;

but otherwise...

-- glen

Reply to
glen herrmannsfeldt

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.