今日はtimer0モジュールです。データブックにあるものほぼそのままでまったく面白くありません。プリスケーラ、タイマ本体とも、1ビット余計に用意して、ハザード無しの出力を用意しています。プリスケーラはWDTと兼用になってます。
----
本日の御託
内閣の支持率がすんごい数字になっている(笑)。昔の派閥推薦による組閣がいいとは決して思わないが、安倍内閣の閣僚を見ていると、なんていうか、自覚が足らんというか、脇が甘いというか...
//
// TIMER0 file register
// (c) 2007 BakaOyaji
// based on Figure 11-6: Block Diagram of the Timer0/WDT Prescaler
// $Id$
//
module timer0_reg (
input clk_i,
input reset_i,
input [ 7:0] data_i, // write port
input we_i,
output [7:0] data_o,
input reset_pre_i, // reset prescaler
input t0cki_i,
input t0se_i,
input t0cs_i,
input [2:0] ps_i,
input psa_i,
output set_t0if_o,
// WDT related
input wdt_i,
output wdt_timeout_o
);
wire t0clk0 ;
assign t0clk0 = (t0cs_i == 1'b0) ? clk_i : (t0se_i ^ t0cki_i) ;
wire ps_clk ;
assign ps_clk = (psa_i == 1'b0) ? t0clk0 : wdt_i ;
reg [8:0] prescale = 9'h00 ;
wire prescale_out ;
always@( posedge ps_clk or posedge reset_pre_i) begin
if( reset_pre_i == 1'b1 ) begin
prescale <= 'd0 ;
end
else begin
prescale <= prescale +1 ;
end // else
end // always
assign prescale_out = prescale[ ps_i +1] ;
assign wdt_timeout_o = psa_i ? wdt_i : prescale_out ;
assign t0clk1 = psa_i ? prescale_out : t0clk0 ;
reg [2:0] dsync;
wire timer0_en ;
always@( posedge clk_i) begin
dsync[2:0] <= { dsync[1:0], t0clk1 } ;
end // always
assign timer0_en = ((dsync[2] ==1'b0) &&(dsync[1] ==1'b1)) ? 1'b1 :1'b0 ;
reg [8:0] timer0 ;
always@( posedge clk_i ) begin
if( reset_i == 1'b0 ) begin
`ifdef FULL_RESET
timer0 <= 9'h0 ;
`endif // FULL_RESET
end // if
else if ( we_i == 1'b1 ) begin
timer0 <= { 1'b0, data_i} ;
end // else if
else if ( timer0_en == 1'b1 ) begin
timer0 <= timer0 + 9'h1 ;
end // else if
end // always
assign data_o = timer0[7:0] ;
assign set_t0if_o = timer0[8] ; // set_t0if_o is hazzerd free
endmodule // timer0_reg
// EOF timer0_reg.v