Iam trying to write a SPI master module by myself to learn FPGA-Verilog efficiently. Here is the spi_master module:
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
And here is the test module;
`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
the spi_master module can be compiled without error but when I try testbench I get this 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
Why is this? Also when I add: reg [15:0] rx_data;
to the spi_master module this time I get this:
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
Why is this happening? I ve read somewhere that says never set inputs as regs. But editor throws exact opposite suggestions. So, to sum up, Are there basic rules for port settings in Verilog? How should I start?
And secondly, I really did not understand why we should not use registers as inputs. Why is that? Where will I store inputs? How will I read them? I think I have to use registers for inputs which is not considered as interrupts. Can someone explain it? I d really appreciate.