Pastel
Member level 3
Hi guys!
It's been a while since my last post, I had to work on other things.
To summarize: I made a signal generator, 8 channels, using a MAX10 and parallel
DACs, and the first part of the design works fine.
I had timing problems at some point, but after re-reading replies (Thanks FVM!!),
I found out that using a PLL to generate my clocks is a lot better. Basically it
fixed everything.
Now I have another problem that looks like a classical one. I needed to communicate
with the FPGA to ask it to send data by SPI to other devices. I first made a very
simple SPI slave engine. NB: There are verilog SPI engines on the net, but a way
too complicated to grasp at once, so I wanted to build my own brew.
The code is shown below. It operates at a single mode (clock pulse positive, I think
it's the (0,0) mode). The version below works perfectly well, but it has to receive
32 bit frames only. If for some reason the MCU transfer is interrupted, then the
data frame (shift_reg) will not be empty but invalid. Not a problem if the next frame is exactly
32 bits, because everything would be cleared by shift, but anyway I would like it to be a bit
cleaner, so as soon as I drop the chip select, I would like to set the shift register to 0.
So basically:
1. On rising edge of the clock, I shift the register left, and add one data bit on
the right.
2. When cs goes high, it means that the transfer is finished, so I output some
parts of the frame. Leds is an array of 6 leds. This works fine. When I receive
a 32 bit frame, I take the last 6 bits and send them to the LEDs. I also have
15 SPI devices driven by the FPGA. I receive the chip id externally and can verify
with the scope that the right bit has been dropped.
3. When the cs goes low, it means that I'm going to receive data. I would like to
clear the shift_reg for a new transfer, but I get this error:
Not only shift_reg[26], I get one error like this per bit.
I have tried to google for this error, and found many replies, but I still don't
understand the problem. The shift_reg is accessed at different events, so I don't
understand where there could be a clash.
Could anybody (try to) explain me what's wrong and how to fix it?
NB: when compiled as shown below, it works. The problem arises when I uncomment
the // shift_reg <=0; line.
NB: I have also checked the similar issues on this forum, but apparently everybody is
using VHDL.
Thanks for any hint!
Pastel
It's been a while since my last post, I had to work on other things.
To summarize: I made a signal generator, 8 channels, using a MAX10 and parallel
DACs, and the first part of the design works fine.
I had timing problems at some point, but after re-reading replies (Thanks FVM!!),
I found out that using a PLL to generate my clocks is a lot better. Basically it
fixed everything.
Now I have another problem that looks like a classical one. I needed to communicate
with the FPGA to ask it to send data by SPI to other devices. I first made a very
simple SPI slave engine. NB: There are verilog SPI engines on the net, but a way
too complicated to grasp at once, so I wanted to build my own brew.
The code is shown below. It operates at a single mode (clock pulse positive, I think
it's the (0,0) mode). The version below works perfectly well, but it has to receive
32 bit frames only. If for some reason the MCU transfer is interrupted, then the
data frame (shift_reg) will not be empty but invalid. Not a problem if the next frame is exactly
32 bits, because everything would be cleared by shift, but anyway I would like it to be a bit
cleaner, so as soon as I drop the chip select, I would like to set the shift register to 0.
Code Verilog - [expand] | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | module inspi ( leds, chip_id, miso, mosi, clk, cs ); output reg[3:0] chip_id; // This will get the address of the slave devices output reg[5:0] leds; // LEDs to check the functionality output reg miso; // As this is a slave, only MISO is output input mosi; input clk; input cs; // Internal variables reg[31:0] shift_reg; // Register to receive the MOSI bits // Initialization initial begin chip_id <= 'hF; // Set the address of the external chips to F (none selected) shift_reg <= 0; end // At every clock, shift and add the current MOSI bit always@(posedge clk) begin shift_reg = shift_reg << 1; if(mosi == 1) begin shift_reg <= shift_reg+1; end end // At end of transfer, CS goes high. Return the LEDs status and chip IDs // received by SPI. All other bits are ignored for the time being. always@(posedge cs) begin leds <= shift_reg[5:0]; chip_id = shift_reg[27:24]; end // At negative edge of CS, we know that the transfer is about to happen. // Set the shift register to 0. always@(negedge cs) begin // shift_reg <= 0; end endmodule |
So basically:
1. On rising edge of the clock, I shift the register left, and add one data bit on
the right.
2. When cs goes high, it means that the transfer is finished, so I output some
parts of the frame. Leds is an array of 6 leds. This works fine. When I receive
a 32 bit frame, I take the last 6 bits and send them to the LEDs. I also have
15 SPI devices driven by the FPGA. I receive the chip id externally and can verify
with the scope that the right bit has been dropped.
3. When the cs goes low, it means that I'm going to receive data. I would like to
clear the shift_reg for a new transfer, but I get this error:
Error (10028): Can't resolve multiple constant drivers for net "shift_reg[26]" at inspi.sv(35)
Not only shift_reg[26], I get one error like this per bit.
I have tried to google for this error, and found many replies, but I still don't
understand the problem. The shift_reg is accessed at different events, so I don't
understand where there could be a clash.
Could anybody (try to) explain me what's wrong and how to fix it?
NB: when compiled as shown below, it works. The problem arises when I uncomment
the // shift_reg <=0; line.
NB: I have also checked the similar issues on this forum, but apparently everybody is
using VHDL.
Thanks for any hint!
Pastel