Signal is connected to multiple drivers

W

WindowsGeek

Guest
I'm a novice at Verilog. I'm writing some glue logic to shift out data
over SPI. My problem code is this:

always @(negedge SPISS)
begin
ADCSPIShifter <= ADCTemp;
end

always @(posedge SPICLK)
begin
SPIMISO = ADCSPIShifter[63];
ADCSPIShifter = ADCSPIShifter << 1;
end

I have a register, ADCTemp, that I created in a different clock
domain. I want to shift this data out over an SPI bus. When the chip
select line (SPISS) goes low, I load the shift register from the
ADCTemp register. On each rising edge of the SPICLK, I want to shift
out a bit of the register.

I know that I'm driving ADCSPIShifter from two sources. I just can't
figure out how to solve it. The chip select line and the SPI clock
line should never transition at the same time, but I don't know how to
tell the synthesizer about that guarantee.

I'm certain there's an easy prepackaged solution to this problem that
everyone who knows anything about Verilog knows. I'm just not one of
those people who learned Verilog the right way. If anyone can suggest
a solution, I'd sure appreciate it.
 
You dont specify the frequency of the clocks. You may need to use an asyn
fifo.

Jon

---------------------------------------
Posted through http://www.FPGARelated.com
 
WindowsGeek <windowsgeek@gmail.com> wrote:
I'm a novice at Verilog. I'm writing some glue logic to shift out data
over SPI. My problem code is this:

always @(negedge SPISS)
begin
ADCSPIShifter <= ADCTemp;
end

always @(posedge SPICLK)
begin
SPIMISO = ADCSPIShifter[63];
ADCSPIShifter = ADCSPIShifter << 1;
end

I have a register, ADCTemp, that I created in a different clock
domain. I want to shift this data out over an SPI bus. When the chip
select line (SPISS) goes low, I load the shift register from the
ADCTemp register. On each rising edge of the SPICLK, I want to shift
out a bit of the register.
It helps if you think of gates and wires, instead of variables,
like you would in C.

If you wired this up with TTL, the outputs of your shift register
would be wired to the outputs of the ADC, which would cause
overheating in the output transistors. The simulator doesn't
overheat, but it also doesn't know what to do.

What you want is a loadable shift register. What you got was
two registers with their outputs connected together.

I know that I'm driving ADCSPIShifter from two sources. I just can't
figure out how to solve it. The chip select line and the SPI clock
line should never transition at the same time, but I don't know how to
tell the synthesizer about that guarantee.
From what you have given, I don't believe I can answer it.

The shift register normally has one clock, and a load enable such
that it loads when the load enable is active, and shifts when it isn't.

-- glen
 
On 11/17/2010 12:21 PM, WindowsGeek wrote:
I'm a novice at Verilog. I'm writing some glue logic to shift out data
over SPI. My problem code is this:

always @(negedge SPISS)
begin
ADCSPIShifter<= ADCTemp;
end

always @(posedge SPICLK)
begin
SPIMISO = ADCSPIShifter[63];
ADCSPIShifter = ADCSPIShifter<< 1;
end

I have a register, ADCTemp, that I created in a different clock
domain. I want to shift this data out over an SPI bus. When the chip
select line (SPISS) goes low, I load the shift register from the
ADCTemp register. On each rising edge of the SPICLK, I want to shift
out a bit of the register.

I know that I'm driving ADCSPIShifter from two sources. I just can't
figure out how to solve it. The chip select line and the SPI clock
line should never transition at the same time, but I don't know how to
tell the synthesizer about that guarantee.

I'm certain there's an easy prepackaged solution to this problem that
everyone who knows anything about Verilog knows. I'm just not one of
those people who learned Verilog the right way. If anyone can suggest
a solution, I'd sure appreciate it.
My knee-jerk response to this would be to look for a clock domain that's
fast enough (at least four times SPICLK, more = better), then do the
whole thing in that clock domain, with an appropriate state machine.

--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com

Do you need to implement control loops in software?
"Applied Control Theory for Embedded Systems" was written for you.
See details at http://www.wescottdesign.com/actfes/actfes.html
 
On Nov 17, 12:21 pm, WindowsGeek <windowsg...@gmail.com> wrote:
I'm a novice at Verilog. I'm writing some glue logic to shift out data
over SPI. My problem code is this:

always @(negedge SPISS)
begin
        ADCSPIShifter <= ADCTemp;
end

always @(posedge SPICLK)
begin
        SPIMISO = ADCSPIShifter[63];
        ADCSPIShifter = ADCSPIShifter << 1;
end

I have a register, ADCTemp, that I created in a different clock
domain. I want to shift this data out over an SPI bus. When the chip
select line (SPISS) goes low, I load the shift register from the
ADCTemp register. On each rising edge of the SPICLK, I want to shift
out a bit of the register.

I know that I'm driving ADCSPIShifter from two sources. I just can't
figure out how to solve it. The chip select line and the SPI clock
line should never transition at the same time, but I don't know how to
tell the synthesizer about that guarantee.

I'm certain there's an easy prepackaged solution to this problem that
everyone who knows anything about Verilog knows. I'm just not one of
those people who learned Verilog the right way. If anyone can suggest
a solution, I'd sure appreciate it.
You need to code it like this.

always @(posedge SPICLK)
begin
if (SPISS = 1'b0)
ADCSPIShifter = ADCTemp;
else
ADCSPIShifter = ADCSPIShifter << 1;
end

assign SPIMISO = ADCSPIShifter[63];

You load the register once with your load signal and then shift it out
as needed.

Ed McGettigan
--
Xilinx Inc.
 
On Nov 17, 3:56 pm, Ed McGettigan <ed.mcgetti...@xilinx.com> wrote:
On Nov 17, 12:21 pm, WindowsGeek <windowsg...@gmail.com> wrote:



I'm a novice at Verilog. I'm writing some glue logic to shift out data
over SPI. My problem code is this:

always @(negedge SPISS)
begin
        ADCSPIShifter <= ADCTemp;
end

always @(posedge SPICLK)
begin
        SPIMISO = ADCSPIShifter[63];
        ADCSPIShifter = ADCSPIShifter << 1;
end

I have a register, ADCTemp, that I created in a different clock
domain. I want to shift this data out over an SPI bus. When the chip
select line (SPISS) goes low, I load the shift register from the
ADCTemp register. On each rising edge of the SPICLK, I want to shift
out a bit of the register.

I know that I'm driving ADCSPIShifter from two sources. I just can't
figure out how to solve it. The chip select line and the SPI clock
line should never transition at the same time, but I don't know how to
tell the synthesizer about that guarantee.

I'm certain there's an easy prepackaged solution to this problem that
everyone who knows anything about Verilog knows. I'm just not one of
those people who learned Verilog the right way. If anyone can suggest
a solution, I'd sure appreciate it.

You need to code it like this.

always @(posedge SPICLK)
begin
      if (SPISS = 1'b0)
        ADCSPIShifter = ADCTemp;
      else
        ADCSPIShifter = ADCSPIShifter << 1;
end

assign SPIMISO = ADCSPIShifter[63];

You load the register once with your load signal and then shift it out
as needed.

Ed McGettigan
--
Xilinx Inc.
Well, that might work. But there are many SPI systems where the clock
does
not run constantly, so the load needs to be asynchronous. Most
designs work
around the asynchronous load requirement by using a (much faster)
internal
system clock to load the register as well as to sample the SPI clock
and data.
The OP did not say whether he has such a free-running clock in his
system.
If not he could code something like:

always @(posedge SPICLK or negedge SPISS)
begin
if (SPISS = 1'b0)
ADCSPIShifter = ADCTemp;
else
ADCSPIShifter = ADCSPIShifter << 1;
end

Then you get to find out whether asynchronous load shift-registers
synthesize
in the architecture of choice.

regards,
gabor
 

Welcome to EDABoard.com

Sponsor

Back
Top