此部分主要是将上一个案例中的状态S2\S3合为一个状态,在A和R之间插入一个寄存器(实际上相当于流水线的原理),在每个时钟周期同时完成两个移位寄存器的移位。要注意的是由于一开始进入S2之前已经载入数据,而后需要9次移位【总共10个周期】。只要进入状态S2,相当于已经经历1个时钟周期完成载入了,还有9个时钟周期,8次移位。因此需要计数8到0,进入时就完成第一次移位,由EA移入R0,同时EA也开始移位,计数会减1。计数从8减到0需要8次,因此到cnt=0时,完成移位运算,将不再继续。
assign EA = (|cnt)&(state ==S2 | (state==S1 & s));
assign ER0 = (state==S2&(|cnt))|(state==S1 &s);
assign ER = (state == S2 & ~cout)&(|cnt);v
代码
下面的代码(2/25)在ER的移位和置零上有错误,2/27再次更新
`timescale 1ns/1ps
module Div(Clk,Rst_n,LA,EB,DataA,DataB,s,R,Q,Done);
parameter n = 8;
input Clk,Rst_n,LA,EB,s;
output [n-1:0] R,Q;
input [n-1:0] DataA,DataB;
output Done ;
parameter S1=2'b00,S2=2'b01,S3=2'b10;
reg [1:0] state,next_state;
wire EC;
reg [3:0] cnt;
reg [n-1:0] B;
wire EA;
wire cout,cin;
wire [n:0] sum ;
reg rr0;
wire ER0;
wire LR,ER,Rsel;
wire [n-1:0] rb;
always@(*) begin
case(state)
S1: if(s) next_state = S2;
S2: if(cnt==0) next_state = S3;
S3: if(~s) next_state = S1;
default: next_state = S1;
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 <= 4'd8;
else if(EC)
cnt <= cnt -1'd1;
else if (Done)
cnt <= 4'd8 ;
end
always@(posedge Clk,negedge Rst_n) begin
if(~Rst_n)
B <= 0;
else if (EB)
B <= DataB;
else if (Done)
B <= 0;
end
always@(posedge Clk,negedge Rst_n) begin
if(~Rst_n)
rr0 <= 0;
else
rr0 <= ER0?Q[n-1]:0;
end
shiftlne shiftA(.Clk(Clk),.La(LA),.Ea(EA),.A(Q),.w(cout),.Data(DataA));
shiftlne shiftR(.Clk(Clk),.La(LR),.Ea(ER),.A(R),.w(rr0),.Data(rb));
assign rb= Rsel?sum[n-1:0]:0;
assign EA = (|cnt)&(state ==S2 | (state==S2 & s));
assign LR = (state == S1 & ~s ) | (state==S2 & cout);
assign ER = (state == S2 & ~cout)&(|cnt);
assign Rsel = (state == S2);
assign cout = sum[n];
assign sum = {1'b0,R[n-2:0],rr0} + {1'b0,~B} + 1'b1;
assign ER0 = (state==S2&(|cnt))|(state==S1 &s);
assign EC = state==S2 ; // | (state==S1&s)
assign Done = state==S3;
endmodule
正确代码如下--------------------------------
`timescale 1ns/1ps
module Div(Clk,Rst_n,LA,EB,DataA,DataB,s,R,Q,Done);
parameter n = 8;
input Clk,Rst_n,LA,EB,s;
output [n-1:0] R,Q;
input [n-1:0] DataA,DataB;
output Done ;
parameter S1=2'b00,S2=2'b01,S3=2'b10;
reg [1:0] state,next_state;
wire EC;
reg [3:0] cnt;
reg [n-1:0] B;
wire EA;
wire cout,cin;
wire [n:0] sum ;
reg rr0;
wire ER0;
wire LR,ER,Rsel;
wire [n-1:0] rb;
always@(*) begin
case(state)
S1: if(s) next_state = S2;
S2: if(cnt==0) next_state = S3;
S3: if(~s) next_state = S1;
default: next_state = S1;
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 <= 4'd8;
else if(EC)
cnt <= cnt -1'd1;
else if (Done)
cnt <= 4'd8 ;
end
always@(posedge Clk,negedge Rst_n) begin
if(~Rst_n)
B <= 0;
else if (EB)
B <= DataB;
else if (Done)
B <= 0;
end
always@(posedge Clk,negedge Rst_n) begin
if(~Rst_n)
rr0 <= 0;
else if(ER0)
rr0 <= ER0?Q[n-1]:0;
else if(Done)
rr0 <= 0;
end
shiftlne shiftA(.Clk(Clk),.La(LA),.Ea(EA),.A(Q),.w(cout),.Data(DataA));
shiftlne shiftR(.Clk(Clk),.La(LR),.Ea(ER),.A(R),.w(rr0),.Data(rb));
assign rb= Rsel?sum[n-1:0]:0;
assign EA = (state ==S2 | (state==S1 & s))&(|cnt);
assign ER0 = (state==S2&(|cnt))|(state==S1 &s);
assign LR = (state == S1 & ~s ) | (state==S2 & cout);
assign ER = (state == S2 & ~cout)&(|cnt);
assign Rsel = (state == S2);
assign cout = sum[n];
assign sum = {1'b0,R[n-2:0],rr0} + {1'b0,~B} + 1'b1;
assign EC = state==S2 ; // | (state==S1&s)
assign Done = state==S3;
endmodule
移位是固定的8次,9个时钟周期。上面的代码中,因为一进入状态S2就移位,那么在state=S1&s时就要给出移位信号,下一个周期A[7]移位到RR0,A[6]移位到A[7];并且在state=S2的最后一个周期不用再次移位,因为cnt=0,代表计数-8,已经完成8次移位。【cnt=7则需要继续移位】R0作为中间的寄存器,最后一个周期不再移位【已经8次】。
移位信号的另一种写法,一进入状态S2的第一个周期不需要A移位,那么在S2最后一个周期还需要给出移位信号。
assign EA = state ==S2;// | (state==S1 & s))&(|cnt);
assign ER0 = (state==S2&(|cnt));//|(state==S1 &s);
assign ER = (state == S2 & ~cout);//&(|cnt);
如果置位为7,那么只有一种情况,开始和结束都移位。
always@(posedge Clk,negedge Rst_n) begin
if(~Rst_n)
cnt <= 4'd7;
else if(EC)
cnt <= cnt -1'd1;
else if (Done)
cnt <= 4'd7 ;
end
assign EA = (state ==S2)| (state==S1 & s);// &(|cnt);
assign ER0 = (state==S2)|(state==S1 &s);;//(&|cnt)
assign ER = (state == S2 & ~cout)//&(|cnt);