CS 3220 Memories and Register Arrays in Verilog • What does this do? reg [15:0] mem; • It creates a 16-bit register (FF), mem[0] is LSB • What is a memory? – Conceptually, it’s a bunch of registers – We use an address to choose which one to access • In Verilog, a memory is described with reg [15:0] mem[0:1023]; • This “mem” has 1024 words, each with 16 bits CS 3220 Fall 2011 - Prof. Milos Prvulovic 2 • File -> New, then “Memory Initialization File” – Now we specify the “format” of the memory – And can edit the memory content – Or write a program to generate this content (Assign2) • Then tell Verilog to use this to initialize our “mem” (* ram_init_file = “SomeFile.mif" *) reg [15:0] mem[0:1023]; • Each memory object can have one of these – E.g. if there is separate inst memory and data memory we can have different .mif files to initialize them CS 3220 Fall 2011 - Prof. Milos Prvulovic 3 (* ram_init_file = "Mem.mif" *) reg [15:0] mem[0:1023]; // 1024-entry, 16-bit memory reg [15:0] mdr; // 16-bit MDR register reg [9:0] mar; // 10-bit MAR register initial mar = 10'd0; // MAR starts with value zero always @(posedge clock) begin mdr <= mem[mar]; // Read memory mar <= mar + 10’d1; // And increment mar register end // Do something with MDR, e.g. display it: SevenSeg sseg0(.IN(mdr[ 3: 0]),.OUT(HEX0)); SevenSeg sseg1(.IN(mdr[ 7: 4]),.OUT(HEX1)); SevenSeg sseg2(.IN(mdr[11: 8]),.OUT(HEX2)); SevenSeg sseg3(.IN(mdr[15:12]),.OUT(HEX3)); CS 3220 Fall 2011 - Prof. Milos Prvulovic 4 always @(posedge clock) begin mar <= mar + 10’d1; // Increment mar register end // Do something with MDR, e.g. display it: SevenSeg sseg0(.IN(mem[mar][ 3: 0]),.OUT(HEX0)); SevenSeg sseg1(.IN(mem[mar][ 7: 4]),.OUT(HEX1)); SevenSeg sseg2(.IN(mem[mar][11: 8]),.OUT(HEX2)); SevenSeg sseg3(.IN(mem[mar][15:12]),.OUT(HEX3)); Compiles (not syntax error). But doesn’t work! always @(posedge clock) begin mar <= mar + 10’d1; // Increment mar register end wire [15:0] memout=mem[mar]; // Do something with MDR, e.g. display it: SevenSeg sseg0(.IN(memout[ 3: 0]),.OUT(HEX0)); SevenSeg sseg1(.IN(memout[ 7: 4]),.OUT(HEX1)); SevenSeg sseg2(.IN(memout[11: 8]),.OUT(HEX2)); SevenSeg sseg3(.IN(memout[15:12]),.OUT(HEX3)); But… note that our memory is now optimized out! CS 3220 Fall 2011 - Prof. Milos Prvulovic 6 • This (almost) always works as expected – Memory address for reading comes from a FF (reg) – Value read from memory only latched into FF (reg) • No logic that “sees” the value directly • (Almost) everything else can misbehave – Unless you know exactly what you are doing • Sometimes you still get surprised • Why? Will come back to this eventually – For now, just read memory using FFs CS 3220 Fall 2011 - Prof. Milos Prvulovic 7 • We can use “LED Debugging” – A close cousin to printf debugging – Use a LED to show the signal of interest, e.g. assign LEDG[0] = mysignal; – Then clock the circuit really slowly (e.g. using a KEY) • Problems with LED Debugging – Very tedious, takes a lot of time to get to the cycle you want (e.g. if the problem is in the 500th cycle) – The key you use for clocking will wear out eventually CS 3220 Fall 2011 - Prof. Milos Prvulovic 8 • We will use SignalTap – Creates a little “oscilloscope” for your design and compiles it together with your design • • • • SignalTap stuff can be expensive (lots of memory bits and LEs) Can make design slower, too So remove SignalTap when bugs are fixed! Our demo design has 38LEs, 10Regs, 16K mem bits w/o SignalTap – Tools->”SignalTap II Logic Analyzer” • • • • • First set your clock signal as the clock for SignalTap Set “Sample Depth” to # of cycles you want to record Right-click the “Instance” and Enable Power-Up Trigger Add wires/regs you want to record Recompile design, program board, then in SignalTap do “Read Data” CS 3220 Fall 2011 - Prof. Milos Prvulovic 9 • Try counting how many times SW[0] went 0->1 • Doesn’t always work as expected – When we move the switch from 0 to 1 position, sometimes the count increment is >1 – When we move the switch from 1 to 0 position, sometimes the count changes! • What’s going on? Bouncing! 1. As contacts get close, vibration causes multiple “touches” before they are firmly together (or apart) 2. Sudden change in current causes voltage to bounce CS 3220 Fall 2011 - Prof. Milos Prvulovic 10 • If it’s used as an edges-are-important signal, it needs a debouncing circuit: – Change output (debounced signal) only if input (SW signal) is stable for multiple clock periods. – This involves a counter, etc. • Why does KEY work just fine? – Because it is already debounced! – Board has a special circuit to “filter” and “condition” KEY signals, but no such circuit on SW CS 3220 Fall 2011 - Prof. Milos Prvulovic 11