学习笔记 : 三态门写法技巧
三态门原理结构图:
(1)、FPGA对外只有一个信号data
(2)、内部有三个信号 wr_en 、wr_data 和 rd_data
先看下面这段很不规范代码,
(1)、always模块里面的信号尽量不要有赋高阻 "z", 只能赋“0” 或赋 “1”;
(2)、always 模块里面尽量不要出现双向信号赋值
(3)、当使用signaltap仿真时,难以定位,因always模块内部有赋高阻的情况,那么当某一时data = 1'b0时,可能就不知道data = 1'b0是从哪里来的,是FPGA内部产生的,还是FPGA外部驱动产生的
1 inout data; //方向是双向 2 /*******************************************************************************/ 3 //在always 里面的信号要么赋"0",要么赋"1",不要出现赋“z” 4 //当使用signaltap仿真时,难以定位,因always模块内部有赋高阻的情况,那么当某一时data = 1'b0时, 5 //可能就不知道data = 1'b0是从哪里来的,是FPGA内部产生的,还是FPGA外部驱动产生的 6 always @(posedge clk or negedge rst_n)begin 7 if(!rst_n)begin 8 data <= 1'bz; //不建议在信号模块里赋高阻 ,避免这种写法 9 end 10 else if(a==1 && b==1) begin 11 data <= 1'b1; 12 end 13 else if(a==1 && c==1)begin 14 data <= 1'b0; 15 end 16 else begin 17 data <= 1'bz; //不建议在信号模块里赋高阻 18 end 19 end 20 21 always @(posedge clk or negedge rst_n)begin 22 if(!rst_n)begin 23 d <= 0; 24 end 25 else begin 26 d <= data; //这里的data是个双向信号 27 end 28 end 29 30 /*******************************************************************************/
规范代码如下:
1 /*******************************************************************************/ 2 inout data; //方向是双向' 3 4 //控制三态门使能 5 always @(posedge clk or negedge rst_n)begin 6 if(!rst_n)begin 7 wr_en <= 1'b0; 8 end 9 else if(a==1 && (b==1 || c==1))begin 10 wr_en <= 1'b1; //打开三态门 11 end 12 else begin 13 wr_en <= 1'b0; //其他条件下关闭三态门 14 end 15 end 16 17 //给输出的赋值,要取决于三态门的关闭或打开,只有在三态门打开时,才会送出 18 always @(posedge clk or negedge rst_n)begin 19 if(!rst_n)begin 20 wr_data <= 1'b0; 21 end 22 else if(a==1 && b==1)begin 23 wr_data <= 1'b1; 24 end 25 else if(a==1 && c==1)begin 26 wr_data <= 1'b0; 27 end 28 else begin 29 wr_data <= 1'b0; 30 end 31 end 32 33 //读数据 34 always @(posedge clk or negedge rst_n)begin 35 if(!rst_n) begin 36 d <= 1'b0; 37 end 38 else begin 39 d <= rd_data; //rd_data 是个单向信号 40 end 41 end 42 43 //下面这段一般放在顶层模块,内部模块就都定义了成单向信号,内部模块的每个信号就都有确定值,要么是“0”,要么是“1”,不会出现高阻态 44 assign data = wr_en ? wr_data : 1'bz; 45 assign rd_data = data; 46 /*******************************************************************************/
规范代码有点:
(1)、一个always模块里只控制一个信号,容易定位问题
(2)、always 模块里不会出现赋高阻态“z” ,信号只能赋 “0” 或 “1” ,都有明确的数值
(3)、双向的信号在顶层模块写好,内部模块就都是单向信号,要么是input 或 output