Estoy tratando de escribir un módulo maestro SPI por mí mismo para aprender FPGA-Verilog de manera eficiente. Aquí está el módulo spi_master:
module spi_master(
output [15:0] tx_data,
input [15:0] rx_data,
output mosi,
input miso,
output cs,
output sck,
input start
);
reg [15:0] tx_data;
reg [3:0] tx_counter;
reg [3:0] rx_counter;
wire start;
reg cs;
reg mosi;
wire miso;
wire sck;
initial begin
tx_counter [3:0] = 4'b0;
rx_counter [3:0] = 4'b0;
end
always @(negedge sck) begin
if (cs == 0 && tx_counter != 4'b1111) begin
#(5) mosi <= tx_data[tx_counter];
#(6) tx_counter <= tx_counter + 4'b1;
end
else if(cs == 0 && tx_counter == 4'b1111) begin
#(5) cs <= 1'b1;
end
else if (cs == 1 && tx_counter == 0) begin
#(5) cs <= 1'b0;
end
end
always @(posedge sck) begin
if (cs == 0 && tx_counter <= 4'b1111 && tx_counter >= 4'b0001) begin
#1 rx_data[rx_counter] <= miso;
#2 rx_counter <= rx_counter + 4'b1;
end
end
endmodule
Y aquí está el módulo de prueba;
`include "spi_master.v"
module spi_master_tb(
);
reg clk;
reg start;
reg mosi;
wire miso;
reg cs;
reg sck;
reg [15:0] tx_data;
initial begin
clk = 0;
tx_data = 16'hF0AA;
#20 start = 1'b1;
#1000 $finish;
sck = 0;
end
always begin
#1 clk = ~clk;
end
always @(start) begin
#10 sck = ~sck; // divided clk by CLK_DIVIDER
end
spi_master SPI_block(
tx_data,
rx_data,
mosi,
miso,
cs,
sck,
start
);
endmodule
el módulo spi_master se puede compilar sin error, pero cuando pruebo el testbench me sale este error:
ERROR:HDLCompiler:1660 - "C:/Users/aozel/Desktop/FPGA Projects/myModule/../Test2/spi_master.v" Line 74: Procedural assignment to a non-register rx_data is not permitted, left-hand side should be reg/integer/time/genvar
¿Por qué? También cuando añado: reg [15:0] rx_data;
al módulo spi_master esta vez obtengo esto:
ERROR:HDLCompiler:661 - "C:/Users/aozel/Desktop/FPGA Projects/myModule/../Test2/spi_master.v" Line 24: Non-net port rx_data cannot be of mode input
¿Por qué ocurre esto? He leído en algún sitio que dice que nunca hay que poner las entradas como regs. Pero el editor lanza sugerencias exactamente opuestas. Así que, para resumir, ¿hay reglas básicas para la configuración de puertos en Verilog? ¿Cómo debería empezar?
Y en segundo lugar, realmente no entendí por qué no debemos utilizar los registros como entradas. ¿Por qué? ¿Dónde voy a almacenar las entradas? ¿Cómo las voy a leer? Creo que tengo que usar registros para las entradas que no se consideran como interrupciones. ¿Alguien puede explicarlo? Se lo agradezco mucho.