verilog编程题-急拉式环形计数器

题目

  1. 写一个如下循环输出的环形计数器
    在这里插入图片描述

代码

主要有一个循环移位计数器和一个状态翻转的flag,需要注意的是循环移位计数器是从8‘h02到8’h80这样移位的,因为总共循环周期是14而不是16。在我们的代码中通过提前使得tmp == 8’h01,接着移位赋值为8‘h02,故而完成功能。

DUT

module jerky_cnt(
	input wire clk,
	input wire rst_n,
	output wire [7:0] count
	);

	
	reg flag;
	always_ff @(posedge clk or negedge rst_n) begin : proc_flag
		if(~rst_n) begin
			flag <= 1'b0;
		end else begin
			flag <= ~flag;
		end
	end
	reg [7:0] tmp;

	always_ff @(posedge clk or negedge rst_n) begin : proc_tmp
		if(~rst_n) begin
			tmp <= 'd1;
		end else if (tmp == 8'h80) begin
			tmp <= 8'h01;
		end else if(flag == 1'b1)begin
			tmp <=  {tmp[6:0],tmp[7]};
		end else begin
			tmp <= tmp;
		end
	end

	assign count = flag ? 7'd1 : tmp;

endmodule

TB

module tb_jerky_cnt();

	reg clk, rst_n;
	wire [7:0] out;

	initial begin 
		clk = 'b0;
		rst_n = 'b0;
		# 10
		rst_n = 'b1;
	end

	always #5 clk = ~clk;

	jerky_cnt dut(
		clk,
		rst_n,
		out
		);


endmodule

仿真

在这里插入图片描述

小结

移位操作往往可以提高运行速度,一个标志flag可以节省资源,但是这种方式容易出错。因为如果状态情况变多,就区分不出来。这种时候可以用计算数器0-13,然后根据计数器的LSB来判断奇偶,如果为偶数就选8’h01,奇数就选1左移(count>>1)。最后还有一种方式用case语句,把所有的情况都列出来进行情况判断。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值