FPGA刷题——数据串转并+数据累加输出

目录

数据串转并

数据累加输出


最近笔试刷题,串并转换和数据累加都是常考点,做法如下

数据串转并

时序图含有的信息较多,观察时序图需要注意:

l  data_b是在已接收到6个数据后下一个时钟产生输出;

l  本模块与上游采用valid_ready握手机制,当valid_a拉低,表示与上游握手未成功,则此时data_a的数据无效,不存入本模块当中;

l  本模块与下游采用valid_only握手机制,这是一种单向指示性握手机制,已接收到6个数据后,valid_b拉高一个时钟周期,指示输出数据有效性

 

要实现6个单bit输入数据的拼接,要用1个寄存器将先到达的数据缓存。当上游握手成功,将输入数据进寄存器,先收到的数据放在低位;当缓存好6个输入数据,valid_b拉高,输出data_b。

需要计数器来计数接收到的数据数量,计数器在0-5之间循环。计数器初始值是0,每接收一个数据,计数器加1,当计数器再次循环到0时,表示已经接收到6个数据,可以输出拼接结果。

module s_to_p(
	input 				clk 		,   
	input 				rst_n		,
	input				valid_a		,
	input	 			data_a		,
 
 	output	reg 		ready_a		,
 	output	reg			valid_b		,
	output  reg [5:0] 	data_b
);
    
    reg [5:0] data_reg;//数据缓存
    reg [2:0] data_cnt;//计数数据个数
    
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            ready_a<=1'd0;//握手信号
        end
        else begin
            ready_a<=1'd1;
        end
    end
    
    always@(posedge clk or negedge rst_n)begin//计数6个数据
        if(!rst_n)begin
            data_cnt<=6'd0;
        end
        else if(ready_a && valid_a) begin
            data_cnt<=(data_cnt==3'd5) ? 3'd0 : (data_cnt+3'd1);
        end
    end
    
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            data_reg<=6'd0;
        end
        else if(ready_a && valid_a) begin
            data_reg<={data_a,data_reg[5:1]}; //缓存数据,按照从低到高
        end
    end
    
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            valid_b <= 'd0;
            data_b <= 'd0;
        end
        else if(data_cnt==3'd5) begin
            valid_b <= 1'd1;  //输出指示信号
            data_b <= {data_a,data_reg[5:1]};//将数据输出
        end
        else begin
            valid_b <= 'd0;
            
        end
    end
    
    
endmodule

通过这个例子,我们不难总结出,串转并的思路

(1)设计数据寄存器+计数器

(2)根据指示信号,根据串转并的数据个数,设置计数器计数个位

(3)根据指示信号,将串行数据移位存入寄存器

(4)当计数器达到数据个数时,将数据输出

同时也可以总结出,并转串的思路

(1)设置数据寄存器+计数器

(2)根据指示信号,根据串转并的数据个数,设置计数器计数个位

(3)根据指示信号,将并行数据移位存入寄存器,输出寄存的数据的最低位

(4)当计数器达到数据个数时,将数据输出

数据累加输出

时序图含有的信息较多,观察时序图需要注意:

l  data_out是在已接收到4个数据后产生输出;

l  在data_out准备好,valid_b拉高时,如果下游的ready_b为低,表示下游此时不能接收本模块的数据,那么,将会拉低ready_a,以反压上游数据输入;

l  当下游ready_b拉高,且valid_b为高,表示模块与下游握手成功,valid_b在下一个时钟周期拉低;

l  当下游ready_b拉高,本来由于之前ready_b为低而反压上游的ready_a立即拉高,开始接收上游数据,注意,此细节,也是体现了题目要求的数据传输无气泡。如果ready_a不是立即拉高,而是在下一个时钟周期拉高,那么本模块将会在下游握手成功后空一个时钟周期,才能开始接收上游数据,这样是不满足题目要求的。

 

要实现4个输入数据的累加,要用1个寄存器将先到达的数据累加之后进行缓存。当上游握手成功,将输入数据累加进寄存器;当累加完4个输入数据,且下游握手成功,将新的输入数据缓存进寄存器。注意,之所以这样设计,是为了不造成性能损失,而之前的累加结果,已经传给了下游。

需要计数器来计数接收到的数据数量,计数器在0-3之间循环。计数器初始值是0,每接收一个数据,计数器加1,当计数器再次循环到0时,表示已经接收到4个数据,可以输出累加结果。

对于ready_a输出信号的产生,如果下游ready_b拉高,表示下游可以接收模块输出数据,那么此时ready_a应拉高,即本模块可以接收上游数据;如果没有接收够4个数据,即valid_b未拉高,那么表示本模块仍可以接收上游数据此时ready_a应拉高。所以综上所述,ready_a信号的产生采用组合逻辑产生。

module valid_ready(
	input 				clk 		,   
	input 				rst_n		,
	input		[7:0]	data_in		,
	input				valid_a		,
	input	 			ready_b		,
 
 	output		 		ready_a		,
 	output	reg			valid_b		,
	output  reg [9:0] 	data_out
);
    reg    [1:0]       data_cnt;
    assign ready_a = !valid_b | ready_b;
    
    always @(posedge clk or negedge rst_n ) begin
    if(!rst_n) 
        data_cnt <= 'd0;
        else if(valid_a && ready_a)//计数器累加4
        data_cnt <= (data_cnt == 2'd3) ? 'd0 : (data_cnt + 1'd1);
    end
    
    
always @(posedge clk or negedge rst_n ) begin
    if(!rst_n) 
        valid_b <= 'd0;
    else if(data_cnt == 2'd3 && valid_a && ready_a)//数据累加到4个
        valid_b <= 1'd1;//输出数据有效信号
    else if(valid_b && ready_b)
        valid_b <= 1'd0;
end
        
always @(posedge clk or negedge rst_n ) begin
    if(!rst_n) 
        data_out <= 'd0;
    else if(ready_b && valid_a && ready_a && (data_cnt == 2'd0))//计数器为0
        data_out <= data_in;//输入数据
    else if(valid_a && ready_a)//数据有效
        data_out <= data_out + data_in;//进行累加
     
end
        
endmodule

总结一下数据累加的方法:

(1)设置一个计数器,根据题目要求,设置计数个数和计数条件

(2)在计数器=0的时候,数据累加 :其实就是在clk下  data_out <= data_out + data_in;最后data_out就是累加值

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值