|
小小萌新,不懂就问 Verilog做一个spi的接受模块遇到的问题 求救
[复制链接]
小小萌新,刚刚入门Verilog,正在做一个spi接受模块 测试阶段出现问题了,不知道怎么用仿真验证接收到的信号
有想过写多个信号发射模块,但是不知道要怎么操作
刚刚入门搞了好久不知道怎么弄了
希望能得到大佬的帮助谢谢
代码如下:
module spi_module
(
input I_clk , // 全局时钟50MHz
input I_rst_n , // 复位信号,低电平有效
input I_rx_en , // 读使能信号
input I_tx_en , // 发送使能信号
input [23:0] I_data_in , // 要发送的数据
output reg [23:0] O_data_out , // 接收到的数据
output reg O_tx_done , // 发送一个字节完毕标志位
output reg O_rx_done , // 接收一个字节完毕标志位
// 四线标准SPI信号定义
input [7:0] I_spi_miso , // SPI串行输入,用来接收从机的数据
output reg O_spi_sck , // SPI时钟
output reg O_spi_cs , // SPI片选信号
output reg O_spi_mosi // SPI输出,用来给从机发送数据
);
reg [5:0] R_tx_state ;
reg [5:0] R_rx_state ;
always @(posedge I_clk or negedge I_rst_n)
begin
if(!I_rst_n)
begin
R_tx_state <= 6'd0 ;
R_rx_state <= 6'd0 ;
O_spi_cs <= 1'b1 ;
O_spi_sck <= 1'b0 ;
O_spi_mosi <= 1'b0 ;
O_tx_done <= 1'b0 ;
O_rx_done <= 1'b0 ;
O_data_out <= 24'd0 ;
end
else if(I_tx_en) // 发送使能信号打开的情况下
begin
O_spi_cs <= 1'b0 ; // 把片选CS拉低
case(R_tx_state)
6'd1, 6'd3 , 6'd5 , 6'd7 ,
6'd9, 6'd11, 6'd13, 6'd15 ,
6'd17, 6'd19, 6'd21, 6'd23 ,
6'd25, 6'd27, 6'd29, 6'd31 ,
6'd33, 6'd35, 6'd37, 6'd39 ,
6'd41, 6'd43, 6'd45, 6'd47 : //整合奇数状态
begin
O_spi_sck <= 1'b1 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd0: // 发送第23位
begin
O_spi_mosi <= I_data_in[23] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd2: // 发送第22位
begin
O_spi_mosi <= I_data_in[22] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd4: // 发送第21位
begin
O_spi_mosi <= I_data_in[21] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd6: // 发送第20位
begin
O_spi_mosi <= I_data_in[20] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd8: // 发送第19位
begin
O_spi_mosi <= I_data_in[19] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd10: // 发送第18位
begin
O_spi_mosi <= I_data_in[18] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd12: // 发送第17位
begin
O_spi_mosi <= I_data_in[17] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd14: // 发送第16位
begin
O_spi_mosi <= I_data_in[16] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd16: // 发送第15位
begin
O_spi_mosi <= I_data_in[15] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd18: // 发送第14位
begin
O_spi_mosi <= I_data_in[14] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd20: // 发送第13位
begin
O_spi_mosi <= I_data_in[13] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd22: // 发送第12位
begin
O_spi_mosi <= I_data_in[12] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd24: // 发送第11位
begin
O_spi_mosi <= I_data_in[11] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd26: // 发送第10位
begin
O_spi_mosi <= I_data_in[10] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd28: // 发送第9位
begin
O_spi_mosi <= I_data_in[9] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd30: // 发送第8位
begin
O_spi_mosi <= I_data_in[8] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd32: // 发送第7位
begin
O_spi_mosi <= I_data_in[7] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd34: // 发送第6位
begin
O_spi_mosi <= I_data_in[6] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd36: // 发送第5位
begin
O_spi_mosi <= I_data_in[5] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd38: // 发送第4位
begin
O_spi_mosi <= I_data_in[4] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd40: // 发送第3位
begin
O_spi_mosi <= I_data_in[3] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd42: // 发送第2位
begin
O_spi_mosi <= I_data_in[2] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd44: // 发送第1位
begin
O_spi_mosi <= I_data_in[1] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
end
6'd46: // 发送第0位
begin
O_spi_mosi <= I_data_in[0] ;
O_spi_sck <= 1'b0 ;
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b1 ;
end
default:R_tx_state <= 6'd0 ;
endcase
end
else if(I_rx_en) // 接收使能信号打开的情况下
begin
O_spi_cs <= 1'b0 ; // 拉低片选信号CS
case(R_rx_state)
6'd0, 6'd2 , 6'd4 , 6'd6 ,
6'd8, 6'd10, 6'd12, 6'd14 ,
6'd16, 6'd18, 6'd20, 6'd22 ,
6'd24, 6'd26, 6'd28, 6'd30 ,
6'd32, 6'd34, 6'd36, 6'd38 ,
6'd40, 6'd42, 6'd44, 6'd46 : //整合偶数状态
begin
O_spi_sck <= 1'b0;
R_rx_state <=R_rx_state + 1'b1;
O_rx_done <= 1'b0;
end
6'd1: // 接收第23位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[23] <= I_spi_miso ;
end
6'd3: // 接收第22位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[22] <= I_spi_miso ;
end
6'd5: // 接收第21位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[21] <= I_spi_miso ;
end
6'd7: // 接收第20位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[20] <= I_spi_miso ;
end
6'd9: // 接收第19位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[19] <= I_spi_miso ;
end
6'd11: // 接收第18位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[18] <= I_spi_miso ;
end
6'd13: // 接收第17位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[17] <= I_spi_miso ;
end
6'd15: // 接收第16位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[16] <= I_spi_miso ;
end
6'd17: // 接收第15位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[15] <= I_spi_miso ;
end
6'd19: // 接收第14位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[14] <= I_spi_miso ;
end
6'd21: // 接收第13位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[13] <= I_spi_miso ;
end
6'd23: // 接收第12位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[12] <= I_spi_miso ;
end
6'd25: // 接收第11位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[11] <= I_spi_miso ;
end
6'd27: // 接收第10位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[10] <= I_spi_miso ;
end
6'd29: // 接收第9位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[9] <= I_spi_miso ;
end
6'd31: // 接收第8位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[8] <= I_spi_miso ;
end
6'd33: // 接收第7位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[7] <= I_spi_miso ;
end
6'd35: // 接收第6位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[6] <= I_spi_miso ;
end
6'd37: // 接收第5位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[5] <= I_spi_miso ;
end
6'd39: // 接收第4位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[4] <= I_spi_miso ;
end
6'd41: // 接收第3位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[3] <= I_spi_miso ;
end
6'd43: // 接收第2位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[2] <= I_spi_miso ;
end
6'd45: // 接收第1位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[1] <= I_spi_miso ;
end
6'd47: // 接收第0位
begin
O_spi_sck <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b1 ;
O_data_out[0] <= I_spi_miso ;
end
default:R_rx_state <= 6'd0 ;
endcase
end
else
begin
R_tx_state <= 6'd0 ;
R_rx_state <= 6'd0 ;
O_tx_done <= 1'b0 ;
O_rx_done <= 1'b0 ;
O_spi_cs <= 1'b1 ;
O_spi_sck <= 1'b0 ;
O_spi_mosi <= 1'b0 ;
O_data_out <= 24'd0 ;
end
end
endmodule
tb:
`timescale 1 ns/ 1 ps
module spi_module_vlg_tst();
reg I_clk;
reg [23:0] I_data_in;
reg I_rst_n;
reg I_rx_en;
reg [7:0]I_spi_miso;
reg I_tx_en;
// wires
wire [23:0] O_data_out;
wire O_rx_done;
wire O_spi_cs;
wire O_spi_mosi;
wire O_spi_sck;
wire O_tx_done;
spi_module i1 (
.I_clk(I_clk),
.I_data_in(I_data_in),
.I_rst_n(I_rst_n),
.I_rx_en(I_rx_en),
.I_spi_miso(I_spi_miso),
.I_tx_en(I_tx_en),
.O_data_out(O_data_out),
.O_rx_done(O_rx_done),
.O_spi_cs(O_spi_cs),
.O_spi_mosi(O_spi_mosi),
.O_spi_sck(O_spi_sck),
.O_tx_done(O_tx_done)
);
initial
begin
I_clk=0;
I_rst_n=0;
I_rx_en=1;
I_tx_en=1;
I_data_in=8'h00;
I_spi_miso=8'h01;
#100;
I_rst_n=1;
end
always
#10 I_clk=~I_clk;
always@(posedge I_clk or negedge I_rst_n)
begin
if(!I_rst_n)
I_data_in <= 8'h00;
else if(I_data_in == 8'hff)
begin
I_data_in <= 8'hff;
I_tx_en <= 0;
end
else if(O_tx_done)
I_data_in <= I_data_in+1'b1;
end
always@(posedge I_clk or negedge I_rst_n)
begin
if(!I_rst_n)
I_spi_miso <= 8'h01;
else if(I_spi_miso == 8'h10)
begin
I_spi_miso <= 8'h10;
I_rx_en <= 0;
end
else if(O_rx_done)
I_spi_miso <= I_spi_miso+1'b1;
end
endmodule
|
|