列表

详情


VL31. 数据累加输出

描述

实现串行输入数据累加输出,输入端输入8bit数据,每当模块接收到4个输入数据后,输出端输出4个接收到数据的累加结果。输入端和输出端与上下游的交互采用valid-ready双向握手机制。要求上下游均能满速传输时,数据传输无气泡,不能由于本模块的设计原因产生额外的性能损失。

电路的接口如下图所示。valid_a用来指示数据输入data_in的有效性,valid_b用来指示数据输出data_out的有效性;ready_a用来指示本模块是否准备好接收上游数据,ready_b表示下游是否准备好接收本模块的输出数据;clk是时钟信号;rst_n是异步复位信号。


接口时序示意图

输入描述

    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

原站题解

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`timescale 1ns/1ns

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]cnt;
    
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n)
            cnt<=2'b00;
        else if(valid_a && ready_a)
            cnt<=cnt+1;
        else if(cnt==2'b11)
            cnt<=0;
    end
    
    //data_out
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n)
            data_out<=0;
        else if(valid_a && ready_a  && cnt==0)
            data_out<=data_in;
        else if(valid_a && ready_a )
            data_out<=data_out+data_in;
        
    end
    
    //valid_b
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n)
            valid_b<=0;
        else if(cnt==2'b11 && valid_a && ready_a)
            valid_b<=1;
        else if(ready_b && valid_b)
            valid_b<=0;
    end
    
    //ready_a
    assign ready_a=(valid_b && ready_b || !valid_b)?1:0;
    
endmodule

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`timescale 1ns/1ns

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 [2:0] cnt;
    
    assign ready_a = (cnt != 3'b100) | ready_b;
    
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            cnt <= 0;
        end
        else if(valid_a && ready_a) begin
            
            if(cnt == 3'b100) begin
                cnt <= 1;
            end
            else begin
                cnt <= cnt + 1;
            end
        end
        else begin
            cnt <= cnt;
        end
    end
    
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            data_out <= 0;
        end
        else if(valid_a && ready_a) begin
            data_out <= cnt == 3'b0 ? data_in : cnt == 3'b100 ? data_in : data_out + data_in;
        end
        else begin
            data_out <= data_out;
        end
    end
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            valid_b <= 0;
        end
        else if(ready_a && valid_a) begin
            valid_b <= cnt == 3'b011;
        end
    end
    
    
endmodule

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`timescale 1ns/1ns

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] cnt;

    assign ready_a=(valid_b=='d0||ready_b=='d1);
    always@(posedge clk or negedge rst_n)begin
        if(~rst_n)
            cnt<='d0;
        else if(valid_a&&ready_a)
            cnt<=cnt+'d1;
    end
    
    always@(posedge clk or negedge rst_n)begin
        if(~rst_n)
            valid_b<='d0;
        else if(cnt=='d3&&valid_a&&ready_a)
            valid_b<='d1;
        else if(valid_b&&ready_b)
            valid_b<='d0;
    end
    
    always@(posedge clk or negedge rst_n)begin
        if(~rst_n)
            data_out<='d0;
        else if(valid_a&&ready_a)
            data_out<=(cnt=='d0)?data_in:data_out+data_in;
        else 
            data_out<=data_out;
    end
   
endmodule

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`timescale 1ns/1ns

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] cnt;
	always @ (posedge clk or negedge rst_n) begin
		if(!rst_n) begin
			cnt <= 2'b0;
		end else if(ready_a&valid_a) begin	
			cnt <= (cnt== 2'd3)?'b0:cnt+1'b1;
		end
	end
	assign ready_a = ready_b| (!valid_b);
	always@(posedge clk or negedge rst_n) begin
		if(!rst_n) begin 
			valid_b <= 1'b0;
		end else if ((cnt=='d3)&(valid_a&ready_a)) begin
			valid_b <= 1'b1;
		end else if ((valid_a&ready_a)) begin
			valid_b <= 1'b0;
		end
	end
	always@(posedge clk or negedge rst_n) begin
		if(!rst_n) begin 
			data_out <= 10'b0;
        end else if ((cnt=='d0)&(valid_a&ready_a)) begin
			data_out <= data_in;
        end else if (valid_a&ready_a) begin
			data_out <= data_out+data_in;

		end
	end
endmodule

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`timescale 1ns/1ns

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
);
    assign ready_a = !valid_b | ready_b;
    reg data_add;
    reg [3:0] data_temp;
    reg [1:0] cnt;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
           cnt <= 0; 
        end
        else begin
           cnt <= cnt==3? 0: valid_a == 1 && ready_a == 1? cnt+1 : cnt; 
        end
    end
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            valid_b <= 0;
        end
        else begin
            valid_b <= cnt ==3 && valid_a  ? 1 : valid_b && ready_b? 0 : valid_b;
        end
    end
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            data_out <= 0;
        end
        else begin
            data_out <= valid_a && ready_a ? (ready_b && cnt == 0)? data_in : data_out +data_in: data_out;
        end
    end
endmodule

上一题