返回模板库
Mealy 可逆计数器Mealy Up/Down Counter
经典 Mealy 型的状态机教学示例:可逆计数器控制,输出取决于状态和输入。
Mealybasicverilog
开源标注
来源仓库: https://555tools.com
许可证: MIT
Author: 555Tools Educational
Copyright (c) 2026 555Tools Educational
Key Points
- - Mealy machine: output depends on state AND input
- - Parameterized counter width
- - Parallel load, up/down mode, overflow/zero flags
- - Two-segment coding: state reg / combined logic
RTL Source
// Copyright (c) 2026 555Tools Educational
// SPDX-License-Identifier: MIT
// Source: https://555tools.com
// Mealy FSM Example: Up/Down Counter with FSM control
// Two-segment coding style (standard for FPGA synthesis)
// 中文:Mealy 型状态机教学示例——可逆计数器控制
`timescale 1ns / 1ps
// Mealy Machine: Output depends on current state AND input
// 中文:Mealy 机——输出取决于当前状态和输入,两段式编码
// 3-bit up/down counter controlled by FSM
// mode=0: count up, mode=1: count down
// load=1: parallel load, enable=1: count
module mealy_counter #(
parameter WIDTH = 3 // Counter width
)(
input wire clk, // System clock
input wire rst, // Synchronous reset
input wire enable, // Count enable
input wire mode, // 0=up, 1=down
input wire load, // Parallel load
input wire [WIDTH-1:0] data_in, // Parallel load data
output reg [WIDTH-1:0] count, // Counter output
output reg overflow, // Count overflow/underflow flag
output reg zero // Counter is zero flag
);
// State encoding
localparam [1:0] S_IDLE = 2'd0, // Waiting for enable
S_COUNT = 2'd1, // Counting
S_LOAD = 2'd2, // Loading parallel data
S_FLAG = 2'd3; // Flag output cycle
reg [1:0] state, next_state;
// Segment 1: State register
always @(posedge clk) begin
if (rst)
state <= S_IDLE;
else
state <= next_state;
end
// Segment 2: Next-state logic (Mealy: depends on inputs)
always @(*) begin
case (state)
S_IDLE: begin
if (load)
next_state = S_LOAD;
else if (enable)
next_state = S_COUNT;
else
next_state = S_IDLE;
end
S_COUNT: begin
if (load)
next_state = S_LOAD;
else if (!enable)
next_state = S_IDLE;
else if (overflow || zero)
next_state = S_FLAG;
else
next_state = S_COUNT;
end
S_LOAD: begin
next_state = S_IDLE;
end
S_FLAG: begin
next_state = S_IDLE;
end
default: next_state = S_IDLE;
endcase
end
// Counter and output logic
always @(posedge clk) begin
if (rst) begin
count <= 0;
overflow <= 0;
zero <= 0;
end else begin
case (state)
S_IDLE: begin
overflow <= 0;
zero <= 0;
end
S_COUNT: begin
if (enable) begin
if (!mode) begin
// Count up
count <= count + 1;
if (count == {WIDTH{1'b1}})
overflow <= 1;
end else begin
// Count down
count <= count - 1;
if (count == 0)
zero <= 1;
end
end
end
S_LOAD: begin
count <= data_in;
overflow <= 0;
zero <= (data_in == 0);
end
S_FLAG: begin
// Mealy output: flag held for one cycle
overflow <= 0;
zero <= 0;
end
default: begin
count <= 0;
overflow <= 0;
zero <= 0;
end
endcase
end
end
endmodule