我是刚进公司实习生,之前没怎么接触过verilog语言,今天师傅让我写这三个模块,说让我看看spi,异步FIFO,我感觉懵懵的,下不了手
其中spi依葫芦画瓢写出来了?那两个模块还不知道咋写?
师傅又说我可以写个测试文档
我现在脑袋里装满了问号?有没有大神指点一下 给我指条路 我接下来该怎么学习这一块知识 ?(我之前专业是信息工程 硬件只学了皮毛 数电 VHDL)
贴一下 spi那一块代码
module SPI
(
input I_clk , //时钟信号
input I_rst , //复位
input I_rx_en , //允许读数据
input I_tx_en , //允许发数据
input [7:0] I_data_in , //
output reg [7:0] O_data_out , //
output reg O_tx_done , //传输完成标志
output reg O_rx_done , //读取完成标志
// spi信号定义
output reg O_CS ,//片选
output reg O_SCLK ,//时钟
output reg O_SDI ,//输出
input I_SDO //输入
);
//0-15读写状态选择
reg[3:0] R_tx_state;
reg[3:0] R_rx_state;
always@(posedge I_clk or negedge I_rst)
begin
if(!I_rst) //复位响应
begin
R_tx_state <= 4'd0 ;
R_rx_state <= 4'd0 ;
O_data_out <= 8'd0 ;
O_tx_done <= 1'd0 ;
O_rx_done <= 1'd0 ;
O_SDI <= 1'd0 ;
O_SCLK <= 1'd0 ;
O_CS <= 1'd1 ;
end
else if(I_tx_en)//发信号
begin
O_CS <= 1'd0 ;
case (R_tx_state)
4'd1, 4'd3 , 4'd5 , 4'd7 , 4'd9, 4'd11, 4'd13, 4'd15 : //整合奇数
begin
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
O_SCLK <= 1'b1 ;
end
4'd0: //第七位
begin
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
O_SDI <= O_data_out[0] ;
O_SCLK <= 1'b0 ;
end
4'd2: //第六位
begin
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
O_SDI <= O_data_out[1] ;
O_SCLK <= 1'b0 ;
end
4'd4: //第五位
begin
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
O_SDI <= O_data_out[2] ;
O_SCLK <= 1'b0 ;
end
4'd6: //第四位
begin
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
O_SDI <= O_data_out[3] ;
O_SCLK <= 1'b0 ;
end
4'd8: //第三位
begin
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
O_SDI <= O_data_out[4] ;
O_SCLK <= 1'b0 ;
end
4'd10: //第二位
begin
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
O_SDI <= O_data_out[5] ;
O_SCLK <= 1'b0 ;
end
4'd12: //第一位
begin
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b0 ;
O_SDI <= O_data_out[6] ;
O_SCLK <= 1'b0 ;
end
4'd14: //第零位
begin
R_tx_state <= R_tx_state + 1'b1 ;
O_tx_done <= 1'b1 ;
O_SDI <= O_data_out[7] ;
O_SCLK <= 1'b0 ;
end
default: R_tx_state <= 4'd0 ;
endcase
end
else if(I_rx_en)//收信号
begin
O_CS <= 1'b0 ; // 拉低片选信号CS
case(R_rx_state)
4'd0, 4'd2 , 4'd4 , 4'd6 , 4'd8, 4'd10, 4'd12, 4'd14 : //整合偶数状态
begin
O_SCLK <= 1'b0 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
end
4'd1: // 接收第7位
begin
O_SCLK <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[7] <= I_SDO ;
end
4'd3: // 接收第6位
begin
O_SCLK <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[6] <= I_SDO ;
end
4'd5: // 接收第5位
begin
O_SCLK <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[5] <= I_SDO ;
end
4'd7: // 接收第4位
begin
O_SCLK <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[4] <= I_SDO ;
end
4'd9: // 接收第3位
begin
O_SCLK <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[3] <= I_SDO ;
end
4'd11: // 接收第2位
begin
O_SCLK <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[2] <= I_SDO ;
end
4'd13: // 接收第1位
begin
O_SCLK <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b0 ;
O_data_out[1] <= I_SDO ;
end
4'd15: // 接收第0位
begin
O_SCLK <= 1'b1 ;
R_rx_state <= R_rx_state + 1'b1 ;
O_rx_done <= 1'b1 ;
O_data_out[0] <= I_SDO ;
end
default:R_rx_state <= 4'd0 ;
endcase
end
else
begin
R_tx_state <= 4'd0 ;
R_rx_state <= 4'd0 ;
O_tx_done <= 1'b0 ;
O_rx_done <= 1'b0 ;
O_CS <= 1'b1 ;
O_SCLK <= 1'b0 ;
O_SDI <= 1'b0 ;
O_data_out <= 8'd0 ;
end
end
endmodule
异步FIFO的可以参考这篇文章:
https://blog.csdn.net/alangaixiaoxiao/article/details/81432144
刚入硬件语言,不要着急;
重点不在于写Verilog HDL程序;
在于懂的每个模块的功能和时序;
也就是说,重点在于设计;
无论是Altera还是Xilinx FPGA都可以作为入门的学习,这些工程也都可以使用Testbench,做仿真;
https://blog.csdn.net/sinat_31206523/article/details/104713955)
鄙人博客分栏,希望可以帮忙。
FPGA设计从硬件到软件
如有问题,也可以私信沟通。