位计数器电路

一个对8位数据进行位计数的位计数器电路的总体思路是简单的,就是对于一个八位数的数据,从最低位到最高位依次判断其是否为1,若为1,则加1。用一个移位寄存器将数据载入后进行移位,数据按位或非后作为判断是否跳出循环的条件。

设计思路:

1、先画出算法状态机,确定三个状态和各个状态下的跳转条件;

2、数据通路电路:移位寄存器,计数器;

3、控制电路:通过状态机确定。

1、顶层模块

顶层部分,输入信号有时钟、复位,载入数据信号,起始触发信号,输入数据,

输出信号有数据,完成信号

代码中主要是三段式状态机,S1,S2,S3三个状态。有以下四个部分

(1)状态转换条件 即next_state(Y)=?

(2)状态跳转触发器 即 state <= next_state

(3)每个状态的控制信号,S1时应该计数器归零,S2时应该保持计数,计数使能信号,提供给移位寄存器移位信号,S3时应该发出完成信号。

(4)数据通路电路(计数器部分),复位时计数器为0,载入信号时计数器为0,有计数使能信号时计数+1

(5)例化移位寄存器,移位寄存器根据载入信号,移位信号,右移数据。输入信号:时钟、补位数据,载入数据,移位信号,载入信号,输出数据。

(6)结束循环的判断信号,移位寄存器中数据按位或非

`timescale 1ns/1ps

module BitCount(Clk,Rst_n,LA,s,Data,B,Done);
	input Clk,Rst_n,LA,s;
	input [7:0] Data;
	output reg [3:0] B;
	output reg Done;
	wire [7:0] A;
	wire z;
	reg [1:0] Y,y;
	reg EA,EB,LB;

	parameter S1 = 2'b00,S2=2'b01,S3=2'b10;

	always@(s,y,z)
	begin:State_table
		case(y)
		S1: 
			if (!s) Y=S1;
			else Y=S2;
		S2:
			if(z==0) Y=S2;
			else Y= S3;
		S3:
			if(s) Y=S3;
			else Y=S1;
		default:Y=S1;
		endcase
	end

	always@(posedge Clk,negedge Rst_n) begin
	y<=~Rst_n?S1:Y;
	end
	
	always @(y,A[0]) begin
	EA=0;LB=0;EB=0;Done=0;
	case(y)
		S1:LB=1;
		S2:begin 
			EA=1;
			if(A[0]) EB=1;
			else EB =0;
			end
		S3:Done=1;
	default:;
	endcase
	end

	always@(posedge Clk,negedge Rst_n) begin 
	if (~Rst_n) 
		B <= 0;
	else if (LB)
		B <= 0;
	else if (EB)
		B <= B +1'b1;
	end
	
	shiftrne ShiftA(.Data(Data),.La(LA),.Ea(EA),.w(1'b0),.Clock(Clk),.A(A));
	assign z= ~|A;

endmodule

2、移位寄存器部分

移位寄存器的输入信号:时钟、原始数据8位、补位数据1位、载入信号、移位信号;

输出:数据

`timescale 1ns/1ps
module shiftrne(Clock,Data,La,Ea,A,w);

input Clock,La,Ea,w;
input [7:0] Data;
output reg [7:0] A;

always @(posedge Clock) begin 
if(La)
	A <= Data;
else if (Ea)
	A <= {w,A[7:1]};
end








endmodule

3、测试仿真

例化模块后,时钟信号定义,输出波形定义,

中间针对输入信号进行设置。复位、数据。

(1)时钟长期工作。首先复位信号有效,然后提供原始数据并且载入数据到移位寄存器中。触发信号为0。

(2)触发信号为1,进行移位并对1计数,计算8个周期完成后【实际上高位为0时要不了8个周期就done】可以改变触发为0

`timescale 1ns/1ps
`define clk_period 20

module tb_bitc();

reg clk,rst_n,s,la;
reg [7:0] data;
wire [3:0] b;
wire done;
BitCount bc0(.Clk(clk),.Rst_n(rst_n),.Data(data),.LA(la),.s(s),.B(b),.Done(done));

initial clk = 1'b0;
always #(`clk_period /2) clk = ~clk;

initial begin 
rst_n = 0 ; la=0;
s = 0 ;
data = 8'd0;
# (5*`clk_period/2) rst_n =1; 
# 20;data=8'b00111011;la=1;
#20;data=8'd0;la=0;
s=1;
#(8*`clk_period);
s=0;
#100;

# 20;data=8'b10111111;la=1;
#20;data=8'd0;la=0;
s=1;
#(8*`clk_period);
s=0;
#100;


# 20;data=8'b00100010;la=1;
#20;data=8'd0;la=0;
s=1;
#(8*`clk_period);
s=0;
#100;

end


initial
begin
  $fsdbDumpfile("curve.fsdb");
  $fsdbDumpvars;
  $fsdbDumpon;
end

initial #5000 $finish;

endmodule

4、脚本运行


vcs -cpp gcc-4.8 -R shiftrne.v BitCount.v tb_bitc.v -P ${NOVAS_HOME}/share/PLI/VCS/linux64/novas.tab ${NOVAS_HOME}/share/PLI/VCS/linux64/pli.a -full64  +v2k -debug_all

理想仿真中,s和clk有效沿同时到来的话,s有效

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值