ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

除法器设计

2022-02-25 11:59:13  阅读:173  来源: 互联网

标签:除法器 clk S3 S2 S1 state 设计 移位


除法器的设计思路比较复杂,主要是移位,相除,将除数和被除数分别放在寄存器B,A,然后,增加一个同样位宽n的移位寄存器R,R中8‘b0作为高位,A中数据作为低位,运算过程需要2n个时钟周期,过程是这样的。

(1)第一个周期进行载入数据A;并且给出计数器减1信号,下一个周期计数器减1,表示已经进行第一次移位。

(2)第二个周期将数据将A中数据最高位移入R;并进行两个判断:判断此时R是否大于等于B,如果大于,则选通R-B,并给出载入LR信号,在下一个周期载入LR,如果R小于B,那么则没有LR信号,并且在下一个周期给出ER信号,在下下一个周期使其移位,再次比较;判断此时计算是否完成,完成的标志是计数器归零,若归零,跳转到完成状态,若没有,进入第三个时钟周期,再次移位...

(3)第三个周期,对A进行移位;给出计数器减1信号;

(4)第四个周期,将A[7]移入R中,并进行判断,判断此时R是否大于等于B,判断此时计算是否结束...

一直进行2n个时钟周期,此时计数器归零,得到商和余数。

1、除法器顶层模块

顶层端口信号:时钟、复位、载入数据信号LA,EB,计算触发信号s,数据A、B,输出商Q,余数R,完成信号Done。

有一些犯错的地方:

(1)最开始写代码时,在从S1进入状态S2后,对A进行了移位,再对R进行的移位,这样的过程漏掉了A的最高位。因此必须严格按照先载入数据后,一定要先让ER有效,移入寄存器R后的下一个周期才让A移位。【进入S2后立即给出了移位信号,但是上一个状态是S1且S3有效,给出了A的移位,因此这个周期中A的最高位实际上是初始的A[6]】

assign EA = (state==S1&s)|(state==S3);
assign ER = state==S2;

(2)计数器的置位为7还是8是有区别的。如果置位为7,进入S2后,就应该立刻进行第一次移位到RA中。此时在S1中由于s=1给出的信号是EA、ER都有效,ER有效保证移入最高位数据,EA有效保证下一个周期时,已经移位,而不会少移位一次。考虑不给出EA有效的情况,由于ER连续两个周期有效,(S1&s 和S2),连续进行两次移位,但是EA最开始并不有效,因此A=11000110会保持两个周期,会连续两个周期读入最高位。因此这种情况下,EA也应该有效,保证第二次移位时,移入的数据是A[6](因为置位为7,并且是一旦进入周期S3,计数-1,计数-1意味着已经移位1次,0=7-7,意味着移位了7次,而最开始state==S1&s时移位一次(处于状态S2),因此R移位8次,即将跳出循环。计数器7到0是对的)

错误情况:

assign EA = (state==S3);//|(state==S1&s);
assign ER = (state==S2)|(state==S1&s);

正确情况
 

assign EA = (state==S3)|(state==S1&s);
assign ER = (state==S2)|(state==S1&s);

如果计数器置位为8,那么应该是如下代码。

assign EA = (state==S3);
assign ER = (state==S2);

(3)关于移位寄存器A,应该在每个状态S2周期都会移位,无论上一个周期S3中是否满足cout=1。

错误情况

assign EA = (state==S3)&cout;

正确情况

assign EA = (state==S3);

(4)R和Q数据复位,由done决定,done决定Q的复位,只要done完成,则复位。(done连接到该寄存器的La载入控制信号),R复位复杂一点,Rsel和LR控制选择信号和载入,载入有效可以是状态S1下且s=0时,或需要载入R-B时(S3下且cout=1),Rsel只有在S3下且cout为1时才载入计算结果R-B。

`timescale 1ns/1ps

module Division(Clk,LA,EB,s,R,Q,DataA,DataB,Rst_n,Done);

parameter n = 8;
input Clk,Rst_n,s,LA,EB;
input [n-1:0] DataA,DataB;
input Done;
output wire [n-1:0] R,Q;

parameter S1=2'b00,S2=2'b01,S3=2'b10,S4=2'b11;
reg [1:0] state,next_state;
reg [2:0] cnt;
wire EC;
wire [n-1:0] A;
wire LR,ER,Rsel;
wire [n:0] sum;
wire [n-1:0] adder_a,adder_b;
wire cout;
wire EQ;
reg [n-1:0] B;

always@(*) begin 
case(state)
S1:
	if(s) next_state = S2;
	else next_state = S1;
S2:	
	next_state = S3;
S3:
	if(cnt==0) next_state = S4;
	else next_state = S2;
S4:	if(s) next_state =S4;
	else next_state = S1;
default:;
endcase
end

always@(posedge Clk ,negedge Rst_n) begin
if(~Rst_n)
	state <= S1;
else
	state <= next_state;
end



always@(posedge Clk ,negedge Rst_n ) begin
if(~Rst_n)
	cnt <= 3'd7;
else if (EC)
	cnt <= cnt - 1'b1;
else if (Done)
	cnt <= 3'd7;
end

assign EC = state==S2;
wire [7:0] datax;
assign datax = Rsel?sum[n-1:0]:8'd0;
shiftlne shiftA(.Clk(Clk),.w(1'b0),.La(LA),.A(A),.Data(DataA),.Ea(EA));
shiftlne shiftRA(.Clk(Clk),.w(A[7]),.La(LR),.Ea(ER),.Data(datax),.A(adder_a));

//Adder adder0(.Cin(1'b1),.Cout(cout),.A(adder_a),.B(adder_b),.Sum(sum));
shiftlne shiftQ(.Clk(Clk),.La(~Rst_n|Done),.Ea(EQ),.Data(8'd0),.w(cout),.A(Q));

always@(posedge Clk,negedge Rst_n) begin
if(~Rst_n) 
	B <= 0;
else if(EB)
	B <= DataB;
end

assign adder_b = ~B;
assign EA = (state==S1&s)|(state==S3);
assign ER = (state==S1&s)|state==S2;
assign LR = ((state==S1)&(s==0))|((state==S3)&cout);
assign EQ = state==S3;
assign sum = {1'b0,adder_a}+{1'b0,adder_b}+1'b1;
assign R = adder_a;
assign cout = sum[n];
assign Done = state==S4;
assign Rsel = (state==S3)&(cout); 

endmodule

2、移位寄存器

`timescale 1ns/1ps 


module shiftlne (Clk,Data,A,La,Ea,w);

parameter n = 8;
input Clk,w;
input [n-1:0] Data;
output reg [n-1:0] A;
input La,Ea;

always@(posedge Clk ) begin 
if(La)
	A <= Data;
else if (Ea)
	A <= {A[14:0],w};
end


endmodule 

3、测试代码

`timescale 1ns/1ps
`define clk_period 20

module tb_Div();

reg clk,rst_n,s,la,lb;
reg [7:0] a,b;
//#wire [15:0] p;
wire done;

wire [7:0] q,r;

Division Div0(.Clk(clk),.Rst_n(rst_n),.DataA(a),.DataB(b),.LA(la),.EB(lb),.s(s),.Q(q),.R(r),.Done(done));

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

initial begin 
rst_n = 0 ; la=0;
s = 0 ;
a = 8'd0; b=8'd0;
# (5*`clk_period/2) rst_n =1; 
# 20;a=8'd200;la=1;lb=1;b=8'd20;
#20;a=8'd0;b=8'b0;la=0;lb=0;
s=1;
#(18*`clk_period);
s=0;
#100;

# 20;a=8'd156;la=1;lb=1;b=8'd3;
#20;a=8'd0;b=8'b0;la=0;lb=0;
s=1;
#(18*`clk_period);
s=0;
#100;


# 20;a=8'd5;la=1;lb=1;b=8'd10;
#20;a=8'd0;b=8'b0;la=0;lb=0;
s=1;
#(18*`clk_period);
s=0;
#100;


# 20;a=8'd105;la=1;lb=1;b=8'd10;
#20;a=8'd0;b=8'b0;la=0;lb=0;
s=1;
#(18*`clk_period);
s=0;
#100;


end


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

initial #5000 $finish;

endmodule

标签:除法器,clk,S3,S2,S1,state,设计,移位
来源: https://blog.csdn.net/baidu_38971369/article/details/123126568

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有