3215|5

3

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

小小萌新,不懂就问 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


此帖出自FPGA/CPLD论坛

最新回复

这说明从设备没有正确接收信息。 或者是芯片有问题,但是一般不会出问题的。 所以你还是看看你的时序是否正确  详情 回复 发表于 2019-6-3 11:55
点赞 关注(1)
 

回复
举报

5979

帖子

8

TA的资源

版主

沙发
 
使用modelsim
此帖出自FPGA/CPLD论坛
个人签名生活就是油盐酱醋再加一点糖,快活就是一天到晚乐呵呵的忙
===================================
做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰
 
 

回复

1173

帖子

3

TA的资源

五彩晶圆(初级)

板凳
 
上传一个银杏科技的例程仅供参考一下,你看一下哪里不对,这个例程是可以的,FPGA与STM32F4通过SPI通信。

13_spi.rar

4.67 MB, 下载次数: 14

此帖出自FPGA/CPLD论坛
 
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

4
 

用modelsim仿真输出信号不会改变呀,不只是哪里出了问题
此帖出自FPGA/CPLD论坛
 
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

5
 
想直接在tb改变接收的信号I_spi_miso看看能否正确运行,但是不知道哪里出错了,I_spi_miso就是不改变,不知道哪里出错了,求助大佬
此帖出自FPGA/CPLD论坛

点评

这说明从设备没有正确接收信息。 或者是芯片有问题,但是一般不会出问题的。 所以你还是看看你的时序是否正确  详情 回复 发表于 2019-6-3 11:55
 
 
 

回复

2113

帖子

0

TA的资源

裸片初长成(初级)

6
 
tzwilson98 发表于 2019-6-3 10:56
想直接在tb改变接收的信号I_spi_miso看看能否正确运行,但是不知道哪里出错了,I_spi_miso就是不改变,不知 ...

这说明从设备没有正确接收信息。
或者是芯片有问题,但是一般不会出问题的。
所以你还是看看你的时序是否正确
此帖出自FPGA/CPLD论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表