📄 ac51_tmr2.v
字号:
//
// ac51_tmr2.v
//
// ac51 microcontroller core
//
// Version 0.6
//
// Copyright 2008, Hideyuki Abe. All rights reserved.
// Distributed under the terms of the MIT License.
//
module ac51_tmr2(
clk,
rst,
ioaddr,
iowdata,
iordata,
iowen,
sck,
rclk,
tclk,
tc2_i,
tc2_o,
t2ex_i,
tf2_req
);
input clk;
input rst;
input [6:0] ioaddr;
input [7:0] iowdata;
output [7:0] iordata;
input iowen;
output sck;
output rclk;
output tclk;
input tc2_i;
output tc2_o;
input t2ex_i;
output tf2_req;
reg [6:0] ioaddr_d;
wire t2con_enb;
wire t2mod_enb;
wire tl2_enb;
wire th2_enb;
wire rcap2l_enb;
wire rcap2h_enb;
wire t2con_wen;
wire t2mod_wen;
wire tl2_wen;
wire th2_wen;
wire rcap2l_wen;
wire rcap2h_wen;
// T2CON bits
wire [7:0] t2con;
reg tf2;
reg exf2;
reg rclk;
reg tclk;
reg exen2;
reg tr2;
reg c_t2;
reg cp_rl2;
// T2MOD bits
wire [7:0] t2mod;
reg dcen;
reg t2oe;
reg [7:0] tl2;
reg [7:0] tl2_nxt;
reg [7:0] th2;
reg [7:0] th2_nxt;
reg [7:0] rcap2l;
reg [7:0] rcap2h;
wire cpt_mode;
wire alu_mode;
wire ald_mode;
wire ckout_mode;
wire brg_mode;
reg [1:0] tc2_seq;
reg [1:0] t2ex_seq;
wire tc2_fall;
wire t2ex_fall;
reg [3:0] t2_presc;
reg t2_cnt;
reg tf2_set;
wire exf2_set;
reg tf2_req;
reg tc2_o;
always @(posedge clk or negedge rst) begin
if(~rst)
ioaddr_d <= 7'h00;
else
ioaddr_d <= ioaddr;
end // always
assign t2con_enb = (ioaddr_d == 7'h48); // T2CON @8'hC8
assign t2mod_enb = (ioaddr_d == 7'h49); // T2MOD @8'hC9
assign tl2_enb = (ioaddr_d == 7'h4c); // TL2 @8'hCC
assign th2_enb = (ioaddr_d == 7'h4d); // TH2 @8'hCD
assign rcap2l_enb = (ioaddr_d == 7'h4a); // RCAP2L @8'hCA
assign rcap2h_enb = (ioaddr_d == 7'h4b); // RCAP2H @8'hCB
assign t2con = {tf2, exf2, rclk, tclk, exen2, tr2, c_t2, cp_rl2};
assign t2mod = {6'b0000_00, t2oe, dcen};
assign iordata = ({8{t2con_enb}} & t2con)
| ({8{t2mod_enb}} & t2mod)
| ({8{tl2_enb}} & tl2)
| ({8{th2_enb}} & th2)
| ({8{rcap2l_enb}} & rcap2l)
| ({8{rcap2h_enb}} & rcap2h);
assign t2con_wen = ((ioaddr == 7'h48) & iowen); // T2CON @8'hC8
assign t2mod_wen = ((ioaddr == 7'h49) & iowen); // T2MOD @8'hC9
assign tl2_wen = ((ioaddr == 7'h4c) & iowen); // TL2 @8'hCC
assign th2_wen = ((ioaddr == 7'h4d) & iowen); // TH2 @8'hCD
assign rcap2l_wen = ((ioaddr == 7'h4a) & iowen); // RCAP2L @8'hCA
assign rcap2h_wen = ((ioaddr == 7'h4b) & iowen); // RCAP2H @8'hCB
always @(posedge clk or negedge rst) begin
if(~rst) begin
rclk <= 1'b0;
tclk <= 1'b0;
exen2 <= 1'b0;
tr2 <= 1'b0;
c_t2 <= 1'b0;
cp_rl2 <= 1'b0;
end
else if(t2con_wen) begin
rclk <= iowdata[5];
tclk <= iowdata[4];
exen2 <= iowdata[3];
tr2 <= iowdata[2];
c_t2 <= iowdata[1];
cp_rl2 <= iowdata[0];
end
end // always
assign cpt_mode = cp_rl2 & (~brg_mode);
assign alu_mode = (~cp_rl2) & (~dcen) & (~ckout_mode) & (~brg_mode);
assign ald_mode = (~cp_rl2) & dcen & (~ckout_mode) & (~brg_mode);
assign ckout_mode = (~cp_rl2) & t2oe;
assign brg_mode = rclk | tclk;
always @(posedge clk or negedge rst) begin
if(~rst)
tf2 <= 1'b0;
else if(t2con_wen)
tf2 <= iowdata[7];
else if(tf2_set & ~brg_mode)
tf2 <= 1'b1;
end // always
always @(posedge clk or negedge rst) begin
if(~rst)
exf2 <= 1'b0;
else if(t2con_wen)
exf2 <= iowdata[6];
else if(ald_mode & dcen) begin
if(tf2_set)
exf2 <= ~exf2;
end
else if(exf2_set & ~ckout_mode)
exf2 <= 1'b1;
end // always
always @(c_t2 or dcen or tf2 or exf2) begin
if(~c_t2) // auto-reload mode
tf2_req = tf2 | (exf2 & ~dcen);
else
tf2_req = tf2 | exf2;
end // always comb
always @(posedge clk or negedge rst) begin
if(~rst) begin
t2oe <= 1'b0;
dcen <= 1'b0;
end
else if(t2mod_wen) begin
t2oe <= iowdata[1];
dcen <= iowdata[0];
end
end // always
// external clk
always @(posedge clk or negedge rst) begin
if(~rst)
tc2_seq <= 2'b11;
else
tc2_seq <= {tc2_seq[0], tc2_i};
end // always
assign tc2_fall = tc2_seq[1] & ~tc2_seq[0];
always @(posedge clk or negedge rst) begin
if(~rst)
t2ex_seq <= 2'b11;
else
t2ex_seq <= {t2ex_seq[0], t2ex_i};
end // always
assign t2ex_fall = t2ex_seq[1] & ~t2ex_seq[0];
assign exf2_set = exen2 & t2ex_fall;
// internal clk
always @(posedge clk or negedge rst) begin
if(~rst)
t2_presc <= 4'd11;
else if(t2_presc == 4'd0)
t2_presc <= 4'd11;
else
t2_presc <= t2_presc - 4'd1;
end // always
always @(
tr2 or c_t2 or brg_mode or ckout_mode
or tc2_fall or t2_presc
) begin
t2_cnt = 1'b0;
if(tr2) begin
if(c_t2) begin
t2_cnt = tc2_fall;
end
else if(brg_mode | ckout_mode) begin
t2_cnt = ~t2_presc[0];
end
else begin
t2_cnt = (t2_presc == 4'd0);
end
end
end // always comb
always @(posedge clk or negedge rst) begin
if(~rst)
tl2 <= 8'h00;
else if(tl2_wen)
tl2 <= iowdata;
else if(alu_mode & (~dcen) & exf2_set)
tl2 <= rcap2l;
else if(t2_cnt)
tl2 <= tl2_nxt;
end // always
always @(
ald_mode or cpt_mode or t2ex_i or tl2 or rcap2l
) begin
if(ald_mode & ~t2ex_i) begin
if(tl2 == 8'h00)
tl2_nxt = 8'hff;
else
tl2_nxt = tl2 - 8'h01;
end
else begin
if(tl2 == 8'hff) begin
if(~cpt_mode)
tl2_nxt = rcap2l;
else
tl2_nxt = 8'h00;
end
else
tl2_nxt = tl2 + 8'h01;
end
end // always comb
always @(posedge clk or negedge rst) begin
if(~rst)
th2 <= 8'h00;
else if(th2_wen)
th2 <= iowdata;
else if(alu_mode & (~dcen) & exf2_set)
th2 <= rcap2h;
else if(t2_cnt)
th2 <= th2_nxt;
end // always
always @(
ald_mode or cpt_mode or t2ex_i or th2 or tl2 or rcap2h
) begin
if(ald_mode & ~t2ex_i) begin
if(tl2 == 8'h00) begin
if(th2 == 8'h00)
th2_nxt = 8'hff;
else
th2_nxt = th2 - 8'h01;
end
else
th2_nxt = th2;
end
else begin
if(tl2 == 8'hff)
if(th2 == 8'hff) begin
if(~cpt_mode)
th2_nxt = rcap2h;
else
th2_nxt = 8'h00;
end
else
th2_nxt = th2 + 8'h01;
else
th2_nxt = th2;
end
end // always comb
always @(t2_cnt or ald_mode or t2ex_i or th2 or tl2) begin
if(t2_cnt) begin
if(ald_mode & ~t2ex_i) begin
if({th2, tl2} == 16'h0000)
tf2_set = 1'b1;
else
tf2_set = 1'b0;
end
else begin
if({th2, tl2} == 16'hffff)
tf2_set = 1'b1;
else
tf2_set = 1'b0;
end
end
else begin
tf2_set = 1'b0;
end
end // always comb
assign sck = brg_mode & tf2_set;
always @(posedge clk or negedge rst) begin
if(~rst)
tc2_o <= 1'b1;
else if(ckout_mode & ~c_t2) begin
if(tf2_set) tc2_o <= ~tc2_o;
end
else
tc2_o <= 1'b1;
end // always
always @(posedge clk or negedge rst) begin
if(~rst)
rcap2l <= 8'h00;
else if(rcap2l_wen)
rcap2l <= iowdata;
else if(cpt_mode & exf2_set)
rcap2l <= tl2;
end // always
always @(posedge clk or negedge rst) begin
if(~rst)
rcap2h <= 8'h00;
else if(rcap2h_wen)
rcap2h <= iowdata;
else if(cpt_mode & exf2_set)
rcap2h <= th2;
end // always
endmodule
// End of ac51_tmr2.v
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -