Search code examples
verilogfpgaxilinxspartan

How do I output a square wave corresponding to a binary number after a delay?


I have three output pins (nCS, DCLK, and DATA0). I am trying to generate all three with an fpga. DATA0 will output the binary number, nCS is a chip select line, and DCLK is the clock (5 Mhz). I am interfacing a memory chip with a specific communication protocol. The bits of DATA0 are output on the falling edge of DCLK and latched into the chip on the rising edge of DCLK. Without any of the if statements in the always block (besides the nested one) and the variable counter, the binary number is output continuously on DATA0.

The problem is when I add the counter code. I want the nCS line to go high for a couple clock cycles and then go low, enabling the device I'm working with. After that, the binary number should be output on the rising edge of the clock. Then that should be repeated. With the code I have now, the ncs line stays high and the data0 line stays low. I would think that the variable counter would go up to four and then keep increasing while the DATA0 bits are output and start over at 1 once the nested if statement is reached. What is the problem here? I'm willing to provide more information and hope you can give me tips on creating better Verilog.

output nCS;
output DCLK;
output DATA0;

reg counter= 1;
wire [7:0] code = 8'b10011111;
reg [7:0] flag = 8'b10000000;
reg ncs;
reg data0 = 0;

always @ (negedge clkdivby8) begin
    if (counter < 4 ) begin
        ncs <= 1'b1;
    end
    else begin
        ncs <= 1'b0;
        data0 <= !(code & flag) ? 1'b0 : 1'b1;
        flag <= flag >> 1;
        if (flag == 8'b1) begin
            flag <= 8'b10000000;
            counter <= 1;
        end
    end
    counter <= counter + 1;
end

assign nCS = ncs;
assign DCLK = clkdivby8; //the 5 MHz clock
assign DATA0 = data0;

Solution

  • I just looked at your code and noticed two major mistakes:

    1. Your counter is defines as a single bit. It it is not possible to count to four with one bit.
    2. This counter <= 1; is never executed. You always increment the counter as the last statement in your clocked section is: counter <= counter + 1; which overrules any previous assignments.

    Last but not least: It is bad practice to use derived clocks in an always @ (pos/negedge ..) statement in your code.
    I don't know where clkdivby8 comes from but the name suggests you have made that clock yourself. If so the whole code section here should be run from your main clock and execute every 8'th clock cycle.