74HC595 Shift Register Assistance


#1

Hi All,

I’m quite new to FPGAs however have a bit of experience with Arduino. I’m looking to hook up 16 LEDs using 2 shift registers however I am having difficulty getting my head around how to implement this in Verilog. I understand how the shift registers work and all the FPGA examples I can find are about implementing the shift register logic in Verilog rather than producing signals to drive the actual chips.

Does anyone have an example code they can share? I’m sure what I’m looking to do will be very obvious when I see the code.

Thanks


#2

I have some code in SpinalHDL to drive a 74HC595 shift register but not in Verilog.

So I will have a go at a Verilog version.

Your top level module will need to declare the clock, data and latch pins, as well as the system clock:

module top (
  input clk_16MHz,
  output shiftout_clock,
  output shiftout_latch,
  output shiftout_data);

// Add logic here

endmodule

For the logic, you will need a shift register and you will normally set shiftout_data to the most significant bit of that if you are shifting MSB first or the LSB if LSB first. Lets assume MSB first:

reg [7:0] shift_reg;

assign shiftout_data = shift_reg[7];

You will need to set the 74HC595 clock. Lets assume for the moment we just set it to the 16Mhz TinyFPGA BX clock:

assign shiftout_clock = clk_16Mhz;

You will need to set the 74HC795 latch high:

assign shiftout_latch = 1;

And then every clock cycle, you will want to shift a bit out:

always @(posedge shiftout_clock) shift_reg <= shift_reg << 1;

What we have not yet done is set the shift register to the data we want to shift out.

One way to do this is to have a bit_counter that we increase by one each time we shift a bit out, so change that always block to:

reg [2:0] bit_counter = 0;
reg [7:0] data_out = 8'h42;

always @(posedge shiftout_clock) begin
  shift_reg <= shift_reg << 1;
  bit_counter <= bit_counter + 1;
  if (bit_counter == 7) shift_reg <= data_out;
end

#3

I have a working version of this:

It did not seem to work with a 16Mhz clock, so I used a clock divider to reduce it to 4Mhz.

I had to use the negative edge of the clock to shift the data out to get the timing right.

The latch needs to be low when the data is shifted out and then set high.

The example counts up slower so you can see the increasing numbers on the leds.

The example could be improved quite a bit and there should be a separate shiftout module.


#4

Thank you so much for that. I’ve been able to get it working on my breadboard and have begun adjusting it to my needs.