⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ac51_tmr2.v

📁 Verilog 8051 IP Core for Cyclone II
💻 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 + -