VL5 位拆分与运算

一、题目

现在输入了一个压缩的16位数据,其实际上包含了四个数据[3:0][7:4][11:8][15:12],

现在请按照sel选择输出四个数据的相加结果,并输出valid_out信号(在不输出时候拉低)

0: 不输出且只有此时的输入有效

1:输出[3:0]+[7:4]

2:输出[3:0]+[11:8]

3:输出[3:0]+[15:12]

信号示意图:

波形图还是不太会分析,缺少testbench参考

二、思路

1、寄存器的位是可以分开单独运算的,并不是一个输入就一定是一个数据,在很多情况下,一个输入既包括数据又包括地址等其他有效信息

2、如何理解“只有此时的输入有效 ”?

仅当sel为0时,输入信号有效,因此需要一个寄存器data_temp,在sel为0时对输入信号进行锁存。即:在sel=0时,把d赋值给data_temp,data_temp稳定输出,一直保持d这个数不变,即锁存。

3、复位时,三个信号受到影响,即data_temp清零、validout清零、输出out清零;

sel为0时,将输入的值锁存到data_temp中,同时validout拉低,输出out为0;(“不输出”可以理解为在sel=0时,输出Out什么事情也不干,就等于0)

sel为1时,validout拉高,同时将锁存后的data_temp按位进行输出out的运算;

sel为2时,validout拉高,同时将锁存后的data_temp按位进行输出out的运算;

sel为3时,validout拉高,同时将锁存后的data_temp按位进行输出out的运算。

4、注意:valid_out信号在不输出时候拉低,rest=0复位,此时out输出为0而不是不输出,只有sel=0时才叫不输出。

三、设计文件

`timescale 1ns/1ns

module data_cal(
input clk,
input rst,
input [15:0]d,
input [1:0]sel,

output reg [4:0]out,
output reg validout
);
//*************code***********//
reg [15:0]data_temp;
always@(posedge clk or negedge rst)
if (!rst)begin
out <= 5'b0;
validout <= 1'b0;
data_temp <= 15'd0;
end
else  begin
    case(sel)
2'b00:begin validout <= 1'b0; out[4:0]<=5'd0;data_temp<=d;end
2'b01:begin validout <= 1'b1; out[4:0]<=data_temp[3:0]+data_temp[7:4];end
2'b10:begin validout <= 1'b1; out[4:0]<=data_temp[3:0]+data_temp[11:8];end
2'b11:begin validout <= 1'b1; out[4:0]<=data_temp[3:0]+data_temp[15:12];end
default begin validout <= 1'b0; out[4:0]<=5'd0;end
    endcase
end

//*************code***********//
endmodule

四、总结

  1. 位拆分

data_temp本来是一个16位的寄存器,data_temp[7:4]指的是把这16位里[7:4]拿出来

2、位拼接

将花括号中罗列的数据依次拼接起来。

比如:d_out={d_in[7],~d_in[6:0]+1'b1};

即是将d_in的最高位和d_in的低7位取反加一拼接起来,拼接之后d_out为8位;

五、锁存器、触发器、寄存器的区别

1、latch同其所有的输入信号相关,当输入信号变化时latch就变化,没有时钟端。主要控制靠的是使能端,当使能端有效时,锁存器的输出与输入相同;当使能端无效时,锁存器输出被锁存,与输入无关;

触发器flip-flop受时钟控制,只有在时钟触发时才采样当前的输入,产生输出。当然因为latch和flip-flop二者都是时序逻辑,所以输出不但同当前的输入相关还同上一时间的输出相关。

2、一般的设计规则是:在绝大多数设计中避免产生latch。

出现锁存器会产生设计者意想不到的后果,并且它的隐蔽性很强,非老手不能查出。latch最大的危害在于不能过滤毛刺。这对于下一级电路是极其危险的。所以,只要能用D触发器的地方,就不用latch。

另一方面要注意,当使用case语句和if…else语句时,一定要注意把可能出现的情况都列出来。如case语句需要使用default关键字把剩余的情况包含起来,而使用if语句最好加上else部分

3、锁存器:电平敏感

always @ (enable)

if (enable) ?q <= d;

那就是说,在enable有效的时间内,q完全跟踪d的值,比如在这个时间内d变化了,q跟着变化,当enable失效的时候,q存储d最后的值。

触发器:我们把输出只在时钟某个时刻变化的玩意儿叫触发器。边沿敏感

always @ (posedge clk)

if (enable) q <= d;

这个便是一个d触发器。只在clk的上升沿q采样d,而且在每个时钟的上升沿都会采样。

在fpga中一般避免用latch,因为在FPGA中触发器资源丰富,不用白不用,latch由于是电平触发的,相对触发器来说容 易产生毛刺,电路不稳定.

latch的优点是完成同一个功能所需要的门较触发器要少,所以在asic中用的较多

那最后再说寄存器,寄存器这个玩意儿是一个概念层次的东西,1个寄存器就是能存1bit数据的东西,把n个触发器的时钟端口连接起来就能构成一个存储n位二进制码的寄存器。既可以用触发器实现也可以用锁存器实现

你可能感兴趣的:(FPGA学习,fpga开发)