前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >08【Verilog实战】4bit移位寄存器设计与功能验证(附源码)[通俗易懂]

08【Verilog实战】4bit移位寄存器设计与功能验证(附源码)[通俗易懂]

作者头像
全栈程序员站长
发布2022-09-13 10:04:26
1.6K0
发布2022-09-13 10:04:26
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

写在前面,4位右移移位寄存器,顾名思义使用四个触发器级联,从一次输入到输出,只移动了3位,而不是4位。比如输入是1101,输出时为0001,而不是0000。


虚拟机:VMware -14.0.0.24051 环 境:ubuntu 18.04.1 脚 本:makefile(点击直达) 应用工具:vcs 和 verdi


文章目录


一、Overview

(1)Theory

  • 行为级描述
在这里插入图片描述
在这里插入图片描述
  • 结构级描述
在这里插入图片描述
在这里插入图片描述

  移位寄存器可以存储数据,还可以用来实现数据的串并转换、分频,构成序列码发生器、序列码检测器等;上图是4位右移寄存器原理图,依据移位寄存器的特点,移位寄存器在时钟的控制下,可将输入数据依次往后移动,N个寄存器级联,最后输出的数据是输入数据的右移N-1位。其中,左边的空位会被补0。其中QD是串行输出端,{QA,QB,QC,QD}可实现并行输出,如果将输出端QD接到输入端QI,则可以实现自循环移位寄存器。

(2)Demand

  1. 当复位信号为0时,输出端全为0;在每个时钟的上升沿时刻,输出端的4位数据向右移一位。
  2. 使用行为级描述和结构建模方式描述。

二、Interface

Signal Name

Width

Direction

Description

clk

1

input

System clk signal, xxMhz

rst

1

input

System reset signal

data

1

input

Detected data

result

1

output

Detection result signal


三、Timeing

在这里插入图片描述
在这里插入图片描述

四、Design and Functional Verification

(1)RTL

代码语言:javascript
复制
//行为级描述
//-- modified by xlinxdu, 2022/04/27
module shift(
  input            clk_i  ,
  input            rst_n_i,
  input            data_i ,
  output reg [3:0] out_o
);
reg [3:0] out_s;

always @ (posedge clk_i or negedge rst_n_i)begin
  if(!rst_n_i)begin
    out_s <= 4'b0;
  end
  else begin
    out_s <= { 
   out_s[2:0],data_i};
  end
end

always @ (posedge clk_i or negedge rst_n_i)begin
  if(!rst_n_i)begin
    out_o <= 4'b0;
  end
  else begin
    out_o <= (out_s >> 3);
  end
end
 
endmodule
代码语言:javascript
复制
//结构级描述
//-- modified by xlinxdu, 2022/04/27
module shift(
  input            clk_i   ,
  input            rst_n_i   ,
  input            data_i  ,
  output reg [3:0] result_o,
  output reg [3:0] out_o
);
reg [2:0] cnt;
reg QA,QB,QC,QD;

always @ (posedge clk_i or negedge rst_n_i)begin
  if(!rst_n_i) begin
    cnt <= 2'b0;
    QA <= 1'b0;
    QB <= 1'b0;
    QC <= 1'b0;
    QD <= 1'b0;
    result_o <= 4'b0;
  end
  else begin
    QA <= data_i;
    QB <= QA;
    QC <= QB;
    QD <= QC;
    result_o <= { 
   QD,QC,QB,QA};
  end
end

always @ (posedge clk_i or negedge rst_n_i)begin
  if(!rst_n_i) begin
    out_o <= 4'b0;
  end
  else begin
    out_o <= { 
   out_o[2:0],QD};
  end
end
endmodule

(2)Test Bench

代码语言:javascript
复制
//行为级描述测试平台
//-- modified by xlinxdu, 2022/04/27
module tb_shift;
  reg clk_i;
  reg rst_n_i;
  reg data_i;
//  wire [3:0] result_o;
  wire [3:0] out_o;

initial begin
  clk_i = 0;
  rst_n_i = 1;
  data_i = 0;
  #10 rst_n_i = 0;
  #10;
  rst_n_i = 1;
end

always #50 clk_i = ~clk_i;
always begin
#100 data_i = 1;
#100 data_i = 1;
#100 data_i = 0;
#100 data_i = 1;
#100;
end
shift tb_shift(
                .clk_i(clk_i),
                .rst_n_i(rst_n_i),
                .data_i(data_i),
//                .result_o(result_o),
                .out_o(out_o)
              );

initial begin
  $fsdbDumpfile("shift.fsdb");
  $fsdbDumpvars              ;
  $fsdbDumpMDA               ;
  #1000 $finish ;
end
endmodule
代码语言:javascript
复制
//结构描述测试平台
//-- modified by xlinxdu, 2022/04/27
module tb_shift;
  reg clk_i;
  reg rst_n_i;
  reg data_i;
  wire [3:0] result_o;
  wire [3:0] out_o;

initial begin
  clk_i = 0;
  rst_n_i = 1;
  data_i = 0;
  #10 rst_n_i = 0;
  #10;
  rst_n_i = 1;
end

always #50 clk_i = ~clk_i;
always begin
#100 data_i = 1;
#100 data_i = 1;
#100 data_i = 0;
#100 data_i = 1;
#100;
end
shift tb_shift(
                .clk_i(clk_i),
                .rst_n_i(rst_n_i),
                .data_i(data_i),
                .result_o(result_o),
                .out_o(out_o)
              );

initial begin
  $fsdbDumpfile("shift.fsdb");
  $fsdbDumpvars              ;
  $fsdbDumpMDA               ;
  #1000 $finish ;
end
endmodule

五、Result

(1)行为级描述测试结果

在这里插入图片描述
在这里插入图片描述

(2)结构级描述测试结果

在这里插入图片描述
在这里插入图片描述

分析:   在行为级描述过程中,输出只与输入有关,每次只会操作就近的四位数据,之外的数据会被丢弃掉,四位内左侧补0,因为每次只有四位数据被赋值到中间变量out_s造成下一次的时候,四位以外的数据丢失了,数据不符合实际电路产生的值(bug)。   在结构级描述过程中,输出与result_o是4位寄存器的并输出端,out_o是移位后数据的输出端,其中输出的值需要看该时刻前面的完整的输入值。比如刚开始的时候,串行输入值为0110时,移位输出值为0000;串行输入值为01101时,移位输出值为0001;串行输入值为0110111时,移位输出值为0110,,依次类推,每来一个时钟,数据右移一位输出。

(3)bug分析

  针对上述情况,分析产生数据丢失的是因为中间的缓存变量每次只缓存4bit数据,而在四位移位寄存器中,要保证数据不被截取掉,至少保证数据位宽为7(移动的3bit+4bit数据)。见下表:

输入

累计数据(4bit)

移位后的数据(>>3)

累计数据(7bit)

移位后的数据(>>3)

a

000a

0000

000_000a

0000

b

00ab

0000

000_00ab

0000

c

0abc

0000

000_0abc

0000

d

abcd

000a

000_abcd

000a

e

bcde

000b

00a_bcde

00ab

f

cdef

000c

0ab_cdef

0abc

g

defg

000d

abc_defg

abcd

h

efgh

000h

bcd_efgh

bcde

  • 更正后的测试波形与结构描述的一一致。
在这里插入图片描述
在这里插入图片描述

作者:xlinxdu 版权:本文是作者原创,版权归作者所有。 转载:未经作者允许,禁止转载,转载必须保留此段声明,必须在文章中给出原文连接。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/160267.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 一、Overview
  • (1)Theory
  • (2)Demand
  • 二、Interface
  • 三、Timeing
  • 四、Design and Functional Verification
  • (1)RTL
  • (2)Test Bench
  • 五、Result
  • (1)行为级描述测试结果
  • (2)结构级描述测试结果
  • (3)bug分析
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档