牛客:VL30 数据串转并电路

本文介绍了一种串并转换电路的设计,使用valid-ready和valid-only握手机制,当输入6个数据后输出拼接的6bit数据。电路设计包括计数器、数据存储和输出状态管理,着重于时钟同步和复位策略。
摘要由CSDN通过智能技术生成

题目

描述

实现串并转换电路,输入端输入单bit数据,每当本模块接收到6个输入数据后,输出端输出拼接后的6bit数据。本模块输入端与上游的采用valid-ready双向握手机制,输出端与下游采用valid-only握手机制。数据拼接时先接收到的数据放到data_b的低位。

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

接口时序示意图

输入描述:

    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

提交结果:

注:题目描述中的波形图与提交结果的波形图不同(存疑);

ready_a 信号复位有效为0,复位后为1,对提交结果有影响,不能直接赋值为零,会不通过。

`timescale 1ns/1ns

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 [2:0] cnt;
reg [5:0] data;
reg tmp_valid_b;

always@(negedge rst_n, posedge clk)begin
	if (~rst_n)
	data <= 0;
	else if (valid_a)
	data <= {data_a, data[5:1]};
end

always@(negedge rst_n, posedge clk)begin
	if (~rst_n)
	data_b <= 0;
	else if (cnt == 5)
	 data_b <= {data_a, data[5:1]};
    //	data_b <= data;
end

always@(negedge rst_n, posedge clk) begin
	if(~rst_n)
	cnt <= 0;
	// else if(valid_a)
	// cnt <= cnt == 5 ? 0 : cnt + 1;
	else
	cnt <= ~valid_a ? cnt :
	       cnt == 5 ? 0 : cnt + 1 ;	
end

always@ (negedge rst_n, posedge clk) begin
	// valid_b <= tmp_valid_b;
	if(~rst_n) begin
	valid_b <= 0;
	ready_a <= 0;
	end
	else begin
	valid_b <= cnt == 5 ? valid_a ? 1 : 0 : 0;
	ready_a <= 1;
	end
end


endmodule

tb文件

`timescale 1ns/1ns
module testbench();
reg clk, rst_n, valid_a, data_a;
wire ready_a, valid_b;
wire [5:0]data_b;

initial begin
	$dumpfile("out.vcd");
	$dumpvars(0,testbench);
    rst_n = 0;
    clk = 0;
    #2 rst_n = 1;
end

always #1 clk = ~clk;

initial begin
    valid_a = 0;
//    data_a = 0;
    #2 valid_a = 1;
    #14 valid_a = 0;
    #2 valid_a = 1;
end

initial begin
	#100 $finish;
end

initial begin
	data_a = 0;
//	#4 data_a = 1;
//	#2 data_a = 0 ;
//	#2 data_a = 1 ;
//	#2 data_a = 0 ;
//	#4 data_a = 1 ;
	#2 data_a = 1;
	#2 data_a = 0 ;
	#4 data_a = 1 ;
	#2 data_a = 0 ;
	#2 data_a = 0 ;
end
//always@(posedge clk) begin
//data_a <= ~data_a;
//end

s_to_p dut(
    .clk(clk),   
	.rst_n(rst_n),
	.valid_a(valid_a),
	.data_a(data_a),
 
 	.ready_a(ready_a),
 	.valid_b(valid_b),
	.data_b(data_b)
);
endmodule

仿真结果

(1)提交通过版本波形

仿真题目描述结果

另外:

讨论中的代码

always@(posedge clk&nbs***bsp;negedge rst_n)begin

在牛客刷题的都知道代码中的or(准确地说是“空格or空格”)复制出来会变成&nbs***bsp

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值