URL
https://opencores.org/ocsvn/pid_controller/pid_controller/trunk
Subversion Repositories pid_controller
Compare Revisions
- This comparison shows the changes necessary to convert path
/pid_controller
- from Rev 10 to Rev 9
- ↔ Reverse comparison
Rev 10 → Rev 9
/trunk/RTL/PID.v
1,4 → 1,6
/* PID controller |
Author: Zhu Xu |
Email: m99a1@yahoo.cn |
|
sigma=Ki*e(n)+sigma |
u(n)=(Kp+Kd)*e(n)+sigma+Kd*(-e(n-1)) |
10,20 → 12,20
Work as Wishbone slave, support Classic standard SINGLE/BLOCK READ/WRITE Cycle |
|
registers or wires |
[15:0]kp,ki,kd,sp,pv; can be both read and written through Wishbone interface, address: 0x0, 0x4, 0x8, 0x12, 0x16 |
[15:0]kpd; read only through Wishbone interface, address: 0x20 |
[15:0]err[0:1]; read only through Wishbone interface, address: 0x24, 0x28 |
[15:0]kp,ki,kd,sp,pv; can be both read and written through Wishbone interface, address: 0x0, 0x4, 0x8, 0xc, 0x10 |
[15:0]kpd; read only through Wishbone interface, address: 0x14 |
[15:0]err[0:1]; read only through Wishbone interface, address: 0x18, 0x1c |
[15:0]mr,md; not accessable through Wishbone interface |
[31:0]p,b; not accessable through Wishbone interface |
[31:0]un,sigma; read only through Wishbone interface, address: 0x32, 0x36 |
[31:0]un,sigma; read only through Wishbone interface, address: 0x20, 0x24 |
|
|
[4:0]of; overflow register, read only through Wishbone interface, address: 0x40 |
of[0]==1 : kpd overflow |
of[1]==1 : err[0] overflow |
of[2]==1 : err[1] overflow |
of[3]==1 : un overflow |
of[4]==1 : sigma overflow |
[4:0]OF; overflow register, read only through Wishbone interface, address: 0x28 |
OF[0]==1 : kpd overflow |
OF[1]==1 : err[0] overflow |
OF[2]==1 : err[1] overflow |
OF[3]==1 : un overflow |
OF[4]==1 : sigma overflow |
[0:15]rl; read lock, when asserted corelated reagister can not be read through Wishbone interface |
[0:7]wl; write lock, when asserted corelated reagister can not be written through Wishbone interface |
|
31,7 → 33,7
|
*/ |
|
`include "PID_defines.v" |
`include "PID_defines.v" |
|
module PID #( |
`ifdef wb_16bit |
45,9 → 47,9
`endif |
adr_wb_nb=16 |
)( |
//Wishbone Slave Interface |
input i_clk, |
input i_rst, //reset when low |
//Wishbone Slave port |
input i_rst, |
input i_wb_cyc, |
input i_wb_stb, |
input i_wb_we, |
71,12 → 73,15
err_1_adr = 7, |
un_adr = 8, |
sigma_adr = 9, |
of_adr = 10; |
OF_adr = 10; |
|
wire rst; |
assign rst=~i_rst; |
|
reg [15:0]kp,ki,kd,sp,pv; |
reg wlkp,wlki,wlkd,wlsp,wlpv; // write lock, if one is high the relevant reg is not writeable |
reg wlkp,wlki,wlkd,wlsp,wlpv; |
|
wire [0:7]wl={wlkp,wlki,wlkd,wlsp,wlpv,3'h0}; // write lock |
wire [0:7]wl={wlkp,wlki,wlkd,wlsp,wlpv,3'h0}; |
|
reg wack; //write acknowledged |
|
133,8 → 138,8
`endif |
|
//state machine No.1 |
always@(posedge i_clk or posedge i_rst) |
if(i_rst)begin |
always@(posedge i_clk or negedge rst) |
if(!rst)begin |
state_0<=0; |
wack<=0; |
kp<=0; |
185,7 → 190,8
|
|
//state machine No.2 |
reg [11:0]state_1; |
reg [14:0]state_2; |
reg state_1; |
|
wire update_kpd; |
assign update_kpd=wack&&(~adr[2])&&(~adr[0])&&adr_check; //adr==0||adr==2 |
193,14 → 199,14
wire update_esu; //update e(n), sigma and u(n) |
assign update_esu=wack&&(adr==4)&&adr_check; |
|
reg rlkpd; // read lock |
reg rlerr_0; // read lock |
reg rlerr_1; // read lock |
reg rla; // read lock |
reg rlsigma; // read lock |
reg rlof; // read lock |
reg rlkpd; |
reg rlerr_0; |
reg rlerr_1; |
reg rla; |
reg rlsigma; |
reg rlOF; |
|
reg [4:0]of; |
reg [4:0]OF; |
reg [15:0]kpd; |
reg [15:0]err[0:1]; |
|
222,13 → 228,27
wire [31:0]sum; |
wire [31:0]product; |
|
wire of_addition[0:1]; |
assign of_addition[0]=(p[15]&&a[15]&&(!sum[15]))||((!p[15])&&(!a[15])&&sum[15]); |
assign of_addition[1]=(p[31]&&a[31]&&(!sum[31]))||((!p[31])&&(!a[31])&&sum[31]); |
wire OF_addition[0:1]; |
assign OF_addition[0]=(p[15]&&a[15]&&(!sum[15]))||((!p[15])&&(!a[15])&&sum[15]); |
assign OF_addition[1]=(p[31]&&a[31]&&(!sum[31]))||((!p[31])&&(!a[31])&&sum[31]); |
|
always@(posedge i_clk or posedge i_rst) |
if(i_rst)begin |
state_1<=12'b000000000001; |
|
|
reg [31:0]reg_sum; |
reg [31:0]reg_product; |
reg reg_OF_addition[0:1]; |
|
always@(posedge i_clk)begin |
reg_sum<=sum; |
reg_OF_addition[0]<=OF_addition[0]; |
reg_OF_addition[1]<=OF_addition[1]; |
reg_product<=product; |
end |
|
always@(posedge i_clk or negedge rst) |
if(!rst)begin |
state_1<=0; |
state_2<=15'b000000000000001; |
wlkp<=0; |
wlki<=0; |
wlkd<=0; |
239,8 → 259,8
rlerr_1<=0; |
rla<=0; |
rlsigma<=0; |
rlof<=0; |
of<=0; |
rlOF<=0; |
OF<=0; |
kpd<=0; |
err[0]<=0; |
err[1]<=0; |
255,113 → 275,137
end |
else begin |
case(state_1) |
12'b000000000001: begin |
if(update_kpd)begin |
state_1<=12'b000000000010; |
wlkp<=1; |
wlkd<=1; |
wlpv<=1; |
rlkpd<=1; |
rlof<=1; |
1: state_1<=0; |
0:begin |
case(state_2) |
15'b0000000000001: begin |
if(update_kpd)begin |
state_2<=15'b000000000000010; |
wlkp<=1; |
wlkd<=1; |
wlpv<=1; |
rlkpd<=1; |
rlOF<=1; |
end |
else if(update_esu)begin |
state_2<=15'b00000000001000; |
wlkp<=1; |
wlki<=1; |
wlkd<=1; |
wlsp<=1; |
wlpv<=1; |
rlkpd<=1; |
rlerr_0<=1; |
rlerr_1<=1; |
rla<=1; |
rlsigma<=1; |
rlOF<=1; |
end |
end |
15'b000000000000010: begin |
p<={{16{kp[15]}},kp}; |
a<={{16{kd[15]}},kd}; |
state_2<=15'b000000000000100; |
state_1<=1; |
end |
15'b000000000000100: begin |
kpd<=reg_sum[15:0]; |
wlkp<=0; |
wlkd<=0; |
wlpv<=0; |
rlkpd<=0; |
rlOF<=0; |
OF[0]<=reg_OF_addition[0]; |
state_2<=15'b000000000000001; |
end |
15'b000000000001000: begin |
p<={{16{~err[0][15]}},~err[0]}; |
a<={31'b0,1'b1}; |
state_2<=15'b000000000010000; |
end |
15'b000000000010000: begin |
state_2<=15'b000000000100000; |
p<={{16{sp[15]}},sp}; |
a<={{16{~pv[15]}},~pv}; |
cout<=1; |
end |
15'b000000000100000: begin |
err[1]<=reg_sum[15:0]; |
OF[2]<=OF[1]; |
|
state_2<=15'b000000001000000; |
end |
15'b000000001000000: begin |
err[0]<=reg_sum[15:0]; |
OF[1]<=reg_OF_addition[0]; |
cout<=0; |
start<=1; |
state_2<=15'b000000010000000; |
end |
15'b000000010000000: begin |
mr_index<=1; |
state_2<=15'b000000100000000; |
end |
15'b000000100000000: begin |
mr_index<=2; |
md_index<=1; |
state_2<=15'b000001000000000; |
end |
15'b000001000000000: begin |
mr_index<=0; |
md_index<=0; |
start<=0; |
state_2<=15'b000010000000000; |
end |
15'b000010000000000: begin |
p<=reg_product; |
a<=sigma; |
state_2<=15'b000100000000000; |
|
end |
15'b000100000000000: begin |
//need modi |
|
p<=reg_product; |
|
state_2<=15'b001000000000000; |
end |
15'b001000000000000: begin |
|
a<=reg_product; |
sigma<=reg_sum; |
OF[3]<=OF[4]|reg_OF_addition[1]; |
OF[4]<=OF[4]|reg_OF_addition[1]; |
state_1<=1; |
|
state_2<=15'b010000000000000; |
|
end |
15'b010000000000000: begin |
a<=reg_sum; //Kpd*err0-Kd*err1 |
p<=sigma; |
OF[3]<=OF[3]|reg_OF_addition[1]; |
state_1<=1; |
state_2<=15'b100000000000000; |
end |
15'b100000000000000: begin |
un<=reg_sum; |
OF[3]<=OF[3]|reg_OF_addition[1]; |
state_2<=15'b000000000000001; |
wlkp<=0; |
wlki<=0; |
wlkd<=0; |
wlsp<=0; |
wlpv<=0; |
rlkpd<=0; |
rlerr_0<=0; |
rlerr_1<=0; |
rla<=0; |
rlsigma<=0; |
rlOF<=0; |
end |
endcase |
end |
else if(update_esu)begin |
state_1<=12'b000000001000; |
wlkp<=1; |
wlki<=1; |
wlkd<=1; |
wlsp<=1; |
wlpv<=1; |
rlkpd<=1; |
rlerr_0<=1; |
rlerr_1<=1; |
rla<=1; |
rlsigma<=1; |
rlof<=1; |
end |
end |
12'b000000000010: begin |
p<={{16{kp[15]}},kp}; |
a<={{16{kd[15]}},kd}; |
state_1<=12'b000000000100; |
end |
12'b000000000100: begin |
kpd<=sum[15:0]; |
wlkp<=0; |
wlkd<=0; |
wlpv<=0; |
rlkpd<=0; |
rlof<=0; |
of[0]<=of_addition[0]; |
state_1<=12'b000000000001; |
end |
12'b000000001000: begin |
p<={{16{~err[0][15]}},~err[0]}; |
a<={31'b0,1'b1}; |
state_1<=12'b000000010000; |
end |
12'b000000010000: begin |
err[1]<=sum[15:0]; |
of[2]<=of[1]; |
p<={{16{sp[15]}},sp}; |
a<={{16{~pv[15]}},~pv}; |
cout<=1; |
state_1<=12'b000000100000; |
end |
12'b000000100000: begin |
err[0]<=sum[15:0]; |
of[1]<=of_addition[0]; |
cout<=0; |
start<=1; |
state_1<=12'b000001000000; |
end |
12'b000001000000: begin |
mr_index<=1; |
state_1<=12'b000010000000; |
end |
12'b000010000000: begin |
mr_index<=2; |
md_index<=1; |
state_1<=12'b000100000000; |
end |
12'b000100000000: begin |
mr_index<=0; |
md_index<=0; |
start<=0; |
p<=product; |
a<=sigma; |
state_1<=12'b001000000000; |
end |
12'b001000000000: begin |
a<=sum; |
sigma<=sum; |
of[3]<=of[4]|of_addition[1]; |
of[4]<=of[4]|of_addition[1]; |
p<=product; |
state_1<=12'b010000000000; |
|
end |
12'b010000000000: begin |
a<=sum; |
of[3]<=of[3]|of_addition[1]; |
p<=product; |
state_1<=12'b100000000000; |
end |
12'b100000000000: begin |
un<=sum; |
of[3]<=of[3]|of_addition[1]; |
state_1<=12'b000000000001; |
wlkp<=0; |
wlki<=0; |
wlkd<=0; |
wlsp<=0; |
wlpv<=0; |
rlkpd<=0; |
rlerr_0<=0; |
rlerr_1<=0; |
rla<=0; |
rlsigma<=0; |
rlof<=0; |
end |
endcase |
end |
|
369,7 → 413,7
wire ready; |
multiplier_16x16bit_pipelined multiplier_16x16bit_pipelined( |
i_clk, |
~i_rst, |
rst, |
start, |
md, |
mr, |
398,7 → 442,7
assign rdata[7]=err[1]; |
assign rdata[8]=un[15:0]; |
assign rdata[9]=sigma[15:0]; |
assign rdata[10]={11'b0,of}; |
assign rdata[10]={11'b0,OF}; |
`endif |
|
`ifdef wb_32bit |
412,7 → 456,7
assign rdata[7]={{16{err[1][15]}},err[1]}; |
assign rdata[8]=un; |
assign rdata[9]=sigma; |
assign rdata[10]={27'b0,of}; |
assign rdata[10]={27'b0,OF}; |
`endif |
|
`ifdef wb_64bit |
426,7 → 470,7
assign rdata[7]={{48{err[1][15]}},err[1]}; |
assign rdata[8]={{32{un[31]}},un}; |
assign rdata[9]={{32{sigma[31]}},sigma}; |
assign rdata[10]={59'b0,of}; |
assign rdata[10]={59'b0,OF}; |
`endif |
|
assign rdata[11]=0; |
437,7 → 481,7
|
|
wire [0:15]rl; |
assign rl={5'b0,rlkpd,rlerr_0,rlerr_1,rla,rlsigma,rlof,5'b0}; |
assign rl={5'b0,rlkpd,rlerr_0,rlerr_1,rla,rlsigma,rlOF,5'b0}; |
|
wire rack; // wishbone read acknowledged |
assign rack=(re&adr_check_1&(~rl[adr_1]))|(re&(~adr_check_1)); |