|
发表于 2018-6-26 11:47:02
|
显示全部楼层
从你的信号描述看,你的start的高脉冲应该是大于计数器的工作时钟的时钟周期的,否则,需要传递一个Start的随路时钟
补充内部代码如下:
1. 需要对Start信号进行跨时钟域的同步处理,同步后进行采样
2. 产生计数器计数使能,在同步后的Start上升沿拉高,计数到同步值后拉低
3. 计数器在计数使能进行计数,并在Start上沿恢复到初始值
推荐Verilog 2001的Coding Style
module counter(
input clk ,
input rst_n ,
input start , // Async
input [9:0] set_count , // Maximum Value of counter
output reg alarm // Counter over flag
);
// Signal Declarations
reg start_sync0;
reg start_sync1;
reg start_sync2;
reg start_sync3;
reg start_pos;
reg cnt_en;
reg [9:0] cnt;
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
start_sync0 <= 1'b0;
start_sync1 <= 1'b0;
start_sync2 <= 1'b0;
start_sync3 <= 1'b0;
end
else begin
start_sync0 <= start;
start_sync1 <= start_sync0;
start_sync2 <= start_sync1;
start_sync3 <= start_sync2;
end
end
always@(*) begin
if ((start_sync2 == 1'b1) && (start_sync3 == 1'b0)) begin // posedge of start
start_pos = 1'b1;
end
else begin
start_pos = 1'b1;
end
end
// Generation of couner enable
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
cnt_en <= 1'b0;
end
else if (start_pos == 1'b1) begin
cnt_en <= 1'b1;
end
else if ( cnt == (set_count - 1'b1)) begin
cnt_en <= 1'b0;
end
end
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
cnt <= {10{1'b0}};
end
else if ((start_pos == 1'b1) || (cnt == (set_count - 1'b1))) begin
cnt <= {10{1'b0}};
end
else if (cnt_en == 1'b1) begin
cnt <= cnt + 1'b1;
end
end
// output alarm generation , 1 cycle later than counter's maximum
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
alarm <= 1'b0;
end
else if ((cnt == (set_count - 1'b1))) begin
alarm <= 1'b1;
end
else begin
alarm <= 1'b0;
end
end
endmodule |
|