【原创】等效采样状态机控制工程(测试通过,待完善说明书)
工程文件:/Files/lwpo2008/SampleLogic.rar
综合后RTL图:
module SampleLogic(
input rst_n,
input iclk,
input trig,
output reg oclk
);
parameter IDLE = 4'b0001,
WAIT_RISE = 4'b0010,
WAIT_FALL = 4'b0100,
WAIT_END = 4'b1000;
parameter PULSE_WIDTH = 9'd50;
parameter LENGTH = 9'd306;
reg [3:0] current_state, //state
next_state;
reg r_data_in0, //detect the risingedge reg
r_data_in1,
o_rising_edge;
reg [8:0] count, //count for delay
delay;
reg [7:0] n_delta_t;
reg count_rst_n;
reg delay_rst_n;
reg count_delta_t;
// sequential circuit
always@(posedge iclk, negedge rst_n) begin
if (!rst_n) begin
current_state <= IDLE;
end
else begin
current_state <= next_state;
end
end
// combinational circuit for state logic
always@(current_state,count,n_delta_t,o_rising_edge,delay) begin
next_state = IDLE;
case (current_state)
IDLE : next_state = o_rising_edge ? WAIT_RISE : IDLE;
WAIT_RISE : next_state = (count == n_delta_t) ? WAIT_FALL : WAIT_RISE;
WAIT_FALL : next_state = (delay == PULSE_WIDTH) ? WAIT_END : WAIT_FALL;
WAIT_END : next_state = (count >= LENGTH) ? IDLE : WAIT_END;
endcase
end
// combinational circuit for output logic
always@(posedge iclk, negedge rst_n) begin
if (~rst_n)
oclk <= 1'b0;
else begin
oclk <= 1'b0;
case (current_state)
IDLE : begin
oclk <= 1'b0;
count_rst_n <= 1'b0;
delay_rst_n <= 1'b0;
count_delta_t <= 1'b0;
end
WAIT_RISE : begin
oclk <= 1'b0;
count_rst_n <= 1'b1;
delay_rst_n <= 1'b0;
count_delta_t <= 1'b1;
end
WAIT_FALL : begin
oclk <= 1'b1;
count_rst_n <= 1'b1;
delay_rst_n <= 1'b1;
end
WAIT_END : begin
oclk <= 1'b0;
count_rst_n <= 1'b1;
delay_rst_n <= 1'b0;
end
endcase
end
end
//detect the rising edge
always@(posedge iclk, negedge rst_n) begin
if (!rst_n) begin
r_data_in0 <= 0;
r_data_in1 <= 0;
end
else begin
r_data_in0 <= r_data_in1;
r_data_in1 <= trig;
end
end
always@(r_data_in0,r_data_in1) begin
o_rising_edge = ~r_data_in0 & r_data_in1; //o_rising_edge output
end
//counter
always@(posedge iclk) begin
if(~count_rst_n)
count <= 9'b0_0000_0000;
else
count <= count + 1'b1;
if(~delay_rst_n)
delay <= 9'b0_0000_0000;
else
delay <= delay + 1'b1;
end
always@(posedge count_delta_t,negedge rst_n) begin
if(~rst_n)
n_delta_t <= 8'd0;
else
n_delta_t <= n_delta_t + 1'b1;
end
endmodule
input rst_n,
input iclk,
input trig,
output reg oclk
);
parameter IDLE = 4'b0001,
WAIT_RISE = 4'b0010,
WAIT_FALL = 4'b0100,
WAIT_END = 4'b1000;
parameter PULSE_WIDTH = 9'd50;
parameter LENGTH = 9'd306;
reg [3:0] current_state, //state
next_state;
reg r_data_in0, //detect the risingedge reg
r_data_in1,
o_rising_edge;
reg [8:0] count, //count for delay
delay;
reg [7:0] n_delta_t;
reg count_rst_n;
reg delay_rst_n;
reg count_delta_t;
// sequential circuit
always@(posedge iclk, negedge rst_n) begin
if (!rst_n) begin
current_state <= IDLE;
end
else begin
current_state <= next_state;
end
end
// combinational circuit for state logic
always@(current_state,count,n_delta_t,o_rising_edge,delay) begin
next_state = IDLE;
case (current_state)
IDLE : next_state = o_rising_edge ? WAIT_RISE : IDLE;
WAIT_RISE : next_state = (count == n_delta_t) ? WAIT_FALL : WAIT_RISE;
WAIT_FALL : next_state = (delay == PULSE_WIDTH) ? WAIT_END : WAIT_FALL;
WAIT_END : next_state = (count >= LENGTH) ? IDLE : WAIT_END;
endcase
end
// combinational circuit for output logic
always@(posedge iclk, negedge rst_n) begin
if (~rst_n)
oclk <= 1'b0;
else begin
oclk <= 1'b0;
case (current_state)
IDLE : begin
oclk <= 1'b0;
count_rst_n <= 1'b0;
delay_rst_n <= 1'b0;
count_delta_t <= 1'b0;
end
WAIT_RISE : begin
oclk <= 1'b0;
count_rst_n <= 1'b1;
delay_rst_n <= 1'b0;
count_delta_t <= 1'b1;
end
WAIT_FALL : begin
oclk <= 1'b1;
count_rst_n <= 1'b1;
delay_rst_n <= 1'b1;
end
WAIT_END : begin
oclk <= 1'b0;
count_rst_n <= 1'b1;
delay_rst_n <= 1'b0;
end
endcase
end
end
//detect the rising edge
always@(posedge iclk, negedge rst_n) begin
if (!rst_n) begin
r_data_in0 <= 0;
r_data_in1 <= 0;
end
else begin
r_data_in0 <= r_data_in1;
r_data_in1 <= trig;
end
end
always@(r_data_in0,r_data_in1) begin
o_rising_edge = ~r_data_in0 & r_data_in1; //o_rising_edge output
end
//counter
always@(posedge iclk) begin
if(~count_rst_n)
count <= 9'b0_0000_0000;
else
count <= count + 1'b1;
if(~delay_rst_n)
delay <= 9'b0_0000_0000;
else
delay <= delay + 1'b1;
end
always@(posedge count_delta_t,negedge rst_n) begin
if(~rst_n)
n_delta_t <= 8'd0;
else
n_delta_t <= n_delta_t + 1'b1;
end
endmodule
综合后RTL图:
高调做事,低调做人