|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
本帖最后由 never1978 于 2011-12-23 13:26 编辑
结构十分简单,宏定为为
·define ONES(n) {(n-1){1'b0},1'b1}
data_bits 为clog2的函数,verilog 参考手册上的clog2给仿真用的,综合的话有warnning,对输入做了赋值,使用不太舒服,自己写了一个,宏是重载data bits 的位宽。
module gecko_timer_lite
#(
parameter TIMER_NUM = 2'b0 ,//=== timer channel number,support multi channel
parameter TIMER_WIDTH = data_bits(TIMER_NUM) ,//=== timer number width
parameter TIMER_CYCLE = 8'd32 ,//=== timer output cycle
parameter TIMER_OPCODE = 4'b0101
)
(
input clk ,
input rst_n ,
input [TIMER_WIDTH-1 : 0] i_timer_restore ,//=== timer restore to zero
input [TIMER_WIDTH-1 : 0] i_timer_en ,//=== timer enable
input [TIMER_WIDTH-1 : 0] i_timer_ack ,//=== timer interrupt clear
output [TIMER_WIDTH-1 : 0] o_timer_on //=== timer count up and issue interrupt
);
//=== opcode[0] = timer self clear and countinus output
//=== opcode[1] = timer ack clear and output level
//=== opcode[2] = timer restore active level
`DATA_BITS ( 16 )
localparam TIMER_RESTORE_ACITE = TIMER_OPCODE[2] ;
localparam TIMER_ACK = TIMER_OPCODE[1] ;
localparam TIMER_MODE = TIMER_OPCODE[0] ;
localparam TIMER_CACHE_ON = TIMER_OPCODE[3] ;
wire [TIMER_NUM-1 : 0] w_timer_eos_count ;//=== timer end of counter
reg [TIMER_WIDTH-1 : 0] r_timer_counter[TIMER_NUM:0] ;//=== timer main counter
generate
genvar i;
begin : timer
for ( i = 0; i < TIMER_NUM; i = i + 1 )
begin
always @ ( posedge clk or negedge rst_n )
if ( ! rst_n )
r_timer_counter <= `TD 1'b0;
else if ( i_timer_restore == TIMER_RESTORE_ACITE )
r_timer_counter <= `TD 1'b0;
else if ( w_timer_eos_count == 1'b1 )
begin
if ( TIMER_ACK == 1'b0 )
r_timer_counter <= `TD 1'b0;
else if ( i_timer_ack == 1'b1 )
r_timer_counter <= `TD 1'b0;
end
else if ( i_timer_en == 1'b1 )
r_timer_counter <= `TD r_timer_counter + `ONES ( TIMER_WIDTH );
else
r_timer_counter <= `TD 1'b0;
assign w_timer_eos_count = r_timer_counter == TIMER_CYCLE;
end
end
endgenerate
generate
genvar j;
if ( TIMER_CACHE_ON == 1'b1 )
begin : timer_cache
reg [TIMER_NUM-1 : 0] r_timer_cache ;//=== timer main counter
for ( j = 0; j < TIMER_NUM; j = j + 1 )
always @ ( posedge clk or negedge rst_n )
if ( ! rst_n )
r_timer_cache[j] <= `TD 1'b0;
else
r_timer_cache[j] <= `TD w_timer_eos_count[j];
assign o_timer_on = r_timer_cache ;
end
else
begin : timer_uncache
assign o_timer_on = w_timer_eos_count ;
end
endgenerate
endmodule |
|