1

I'm working on a Verilog project for the DE10-Lite FPGA board that interfaces with a 3-axis accelerometer over SPI. I have separate SPI modules (spi_ee_config) for each axis: x_info, y_info, and z_info. Each module outputs its own chip select (oSPI_CSN) and clock (oSPI_CLK) signals. However, when I try to compile, I get the following error:

The error

Module header for all 3 axis

From what I understand, this means multiple modules are trying to use the same wire, which causes a conflict. But since I'm reading from 3 axes, I'm not sure how to share the SPI bus properly without hitting this error.

How should I structure my Verilog code so only one module drives the CS and CLK lines at a time? Should I mux the outputs manually, or is there a better pattern for handling multiple SPI modules that share the same bus?

Any guidance or code snippets would be appreciated.

Code issue:

Conflict here as all 3 spi_ee_config_# use the same SPI controller:

spi_ee_config_X x_info (            
                            .oSPI_CSN(GSENSOR_CS_N),
                            .oSPI_CLK(GSENSOR_SCLK)
    );

spi_ee_config_y y_info (            
                        .oSPI_CSN(GSENSOR_CS_N),
                        .oSPI_CLK(GSENSOR_SCLK)
);

spi_ee_config_z z_info (            
                        .oSPI_CSN(GSENSOR_CS_N),
                        .oSPI_CLK(GSENSOR_SCLK)
);

Roots back to spi_controller:

module spi_controller (     
input                             iRSTN;
input                             iSPI_CLK;
input                             iSPI_CLK_OUT;
input         [SI_DataL:0]  iP2S_DATA; 
input                           iSPI_GO;
output                        oSPI_END;
output  reg [SO_DataL:0]    oS2P_DATA;
//  SPI Side              
inout                             SPI_SDIO;
output                        oSPI_CSN;    <<<<<<
output                          oSPI_CLK;  <<<<<<<


//  Structural coding
assign read_mode = iP2S_DATA[SI_DataL];
assign write_address = spi_count[3];
assign oSPI_END = ~|spi_count;
assign oSPI_CSN = ~iSPI_GO;
assign oSPI_CLK = spi_count_en ? iSPI_CLK_OUT : 1'b1;
assign SPI_SDIO = spi_count_en && (!read_mode || write_address) ? iP2S_DATA[spi_count] : 1'bz;

always @ (posedge iSPI_CLK or negedge iRSTN) 
    if (!iRSTN)
    begin
        spi_count_en <= 1'b0;
        spi_count <= 4'hf;
    end
    else 
    begin
        if (oSPI_END)
            spi_count_en <= 1'b0;
        else if (iSPI_GO)
            spi_count_en <= 1'b1;
            
        if (!spi_count_en)  
        spi_count <= 4'hf;      
        else
            spi_count   <= spi_count - 4'b1;

    if (read_mode && !write_address)
          oS2P_DATA <= {oS2P_DATA[SO_DataL-1:0], SPI_SDIO};
    end

endmodule
0

1 Answer 1

1

Should I mux the outputs ... ?

Yes. Here is some sample code for a mux for the serial clock:

logic [2:0] sclk;
logic spi_sclk;
logic [1:0] select;

spi_ee_config_X x_info (            
    .oSPI_CSN (GSENSOR_CS_N),
    .oSPI_CLK (sclk[0])
);

spi_ee_config_y y_info (            
    .oSPI_CSN (GSENSOR_CS_N),
    .oSPI_CLK (sclk[1])
);

spi_ee_config_z z_info (            
    .oSPI_CSN (GSENSOR_CS_N),
    .oSPI_CLK (sclk[2])
);

always_comb begin
    case (select)
        0      : spi_sclk = sclk[0];
        1      : spi_sclk = sclk[1];
        default: spi_sclk = sclk[2];
    endcase
end

You would do something similar for the slave-select signals.

Sign up to request clarification or add additional context in comments.

2 Comments

This works directly, but you can also wire a command into the SPI to address X,Y,Z data. Then you have one module instead of three for the SPI. You also multiplex, but it is cs/data instead of SPI clock. In the current code, you need to make the select, to update new x,y,z data (SPI read). You can just register the SPI data output for each select. The spi module usually have some overhead, and resulting code seems just as 'clean'.
You can also make the I/O a bus (tri-state), but both this answer and solution in comment above are better. I think you also have some conflicts. Are the SPI modules 'peripherals' and the FPGA is a 'controller'? You can not share SDIO between three chip and have CS at the same time. So it seems more important that CS is multiplexed (and hence iSPI_GO, which is a disconnect?). Ie, normal wiring is all SPI lines are shared except the CS line. (and in this context, my comment makes more sense).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.