Untitled

mail@pastecode.io avatar
unknown
verilog
a year ago
2.6 kB
1
Indexable
Never
`timescale 1ns/1ps
module Parameterized_Ping_Pong_Counter (
    input clk, 
    input rst_n, 
    input enable, 
    input flip, 
    input [3:0] max, 
    input [3:0] min, 
    output reg direction, 
    output reg [3:0] out
);

// Output signals can be reg or wire
// add your design here

parameter UP = 1'b1;
parameter DOWN = 1'b0;

reg [3:0] nxt_out;
reg nxt_dir;

// Reset signal and deal with output
always @(posedge clk) begin
    if(!rst_n)begin
        out <= min;
        nxt_out <= min;
        direction <= UP;
        nxt_dir <= UP;
    end
    else begin
        if(enable)begin
            out <= nxt_out;
            direction <= nxt_dir;
        end
        else begin
            out <= out;
            direction <= direction;
        end
    end
end

// Deal with flip
// Deal with Cnt
always @(*) begin
    if(max < min) begin
        nxt_out = out;
        nxt_dir = direction;
    end
    else if(min == out || max == out) begin
        if(min == max && min == out) begin
            nxt_out = out;
            nxt_dir = direction;
        end
        else begin
            case (direction)
            UP: begin
                nxt_out = out + 1;
            end 
            DOWN: begin
                nxt_out = out - 1;
            end
            default: nxt_out = out;
            endcase
        
            if(min <= nxt_out && nxt_out <= max) begin
                nxt_out = nxt_out;
            end
            else begin
                nxt_dir = !direction;
                case (nxt_dir)
                    UP: begin
                        nxt_out = out + 1;
                    end 
                    DOWN: begin
                        nxt_out = out - 1;
                    end
                default: nxt_out = out;
                endcase
            end
        end
    end
    else if(min < out && out < max) begin
        if(flip) nxt_dir = !direction;
        else nxt_dir = direction;

        case (nxt_dir)
            UP: begin
                nxt_out = out + 1;
            end 
                DOWN: begin
                nxt_out = out - 1;
            end
            default: nxt_out = out;
        endcase
    end
    else if(out == min - 1 && direction == UP || out == max + 1 && direction == DOWN) begin
        case (direction)
        UP: begin
            nxt_out = out + 1;
        end 
        DOWN: begin
            nxt_out = out - 1;
        end
        default: nxt_out = out;
        endcase
        nxt_dir = direction;
    end
    else begin
        nxt_out = out;
        nxt_dir = direction;
    end
end

endmodule