Actualmente estoy intentando implementar un módulo simple SPI Master en Verilog utilizando Quartus Prime Lite V15.1.0 Build 185 para compilación y Simulation Waveform Editor como mi herramienta de simulación. El módulo ha sido diseñado para funcionar de manera ideal de manera que usted cargue un valor de 8 bits en un bus, alternar un bit de 'transmisión' que le dice al módulo que envíe el valor, y finalmente el módulo responde con un 'hecho' bit para notificar al módulo host que se envió el byte. El módulo SPI no controla las líneas CS, ya que se supone que serán controladas por el módulo maestro.
//CPOL 0, CPHA 0 RIC60 SPI Master module
module SPI (
output reg MOSI, // Map to external I/O pin that will act as MOSI for the spi interface
output wire SCLK, // Map to external I/O pin that will act as SCLK for the spi interface
output wire DATAEN, // Map to external I/O pin that will act as DATAEN for the spi interface
input wire [7:0] inData,// Data to be sent over SPI
input wire CLK, // System clock
input wire datCLK, // Clock to be used for SPI
input wire transmit, // Trigger for when to send out SPI command
output reg done, // signal to trigger finished SPI comm
input wire reset); // System reset input
reg _moduleActive, _moduleActiveQue;
reg [7:0] _inData_INT;
reg [7:0] _countDown;
wire _shiftData;
reg _DCLK2, _DCLK3;
wire _DCLK_FALL, _DCLK_RISE;
reg _Transmit2, _Transmit3;
wire _Transmit_FALL, _Transmit_RISE;
//Initialize
initial begin
_moduleActive = 0;
_moduleActiveQue = 0;
//_countDown[7:0] = 8'b01001100;
MOSI = 0;
end
//SPI Clock catch edges
always@(posedge CLK)
begin
_DCLK2 <= datCLK;
end
assign _DCLK_FALL = (_DCLK2)&(~datCLK);
assign _DCLK_RISE = (~_DCLK2)&(datCLK);
//Transmit catch edges
always@(posedge CLK)
begin
_Transmit2 <= transmit;
end
assign _Transmit_RISE = (!_Transmit2)&(transmit);
//que module start at next rising edge of SPI clock
always @ (posedge CLK) begin
if (_Transmit_RISE) begin
_moduleActiveQue = 1;
end else if (_moduleActive) begin
_moduleActiveQue = 0;
end
end
//put module into 'active' state
always @ (posedge CLK) begin
if (_moduleActiveQue && _DCLK_FALL) begin
_moduleActive = 1;
end else if (_countDown == 0) begin
_moduleActive = 0;
end
end
//set SPI clock
assign SCLK = datCLK && _moduleActive;
//clock out data
always @ (posedge CLK) begin
if (_moduleActiveQue && _DCLK_FALL) begin
_inData_INT = inData;
_countDown = 8'b10101010;
end else if (_moduleActive && _DCLK_RISE) begin
MOSI <= _inData_INT[7];
_inData_INT <= _inData_INT << 1;
_countDown <= _countDown << 1;
end
end
endmodule
El módulo funciona utilizando un 'contador' compuesto por un valor relleno de 1, y los cambios de bits en cada reloj hasta que se igualan a 0. Actualmente este bus de contador, denunciado _countDown, es lo que está demostrando proporcionar el mayor dolor de cabeza. Cuando se simula el código anterior, produce las formas de onda como se ve en la ventana de formas de onda a continuación.
Elbitmenossignificativode_countDownpareceestaratascadoaaltaimpedanciaynocuentaatráscomoesperaríadelcódigodado.Además,comohabránotado,enelbloquede"inicio inicial" se ha comentado la inicialización de _countDown. Si esta línea de código no tiene comentarios, encuentro que _countDown siempre permanece en un estado de alta impedancia. Soy relativamente inexperto con Verilog (que puede aparecer en el código), por lo que cualquier puntero sería muy apreciado.