blob: ce48662a84d143b8cee54b475e0cf3bd7a7954e4 [file] [log] [blame]
// SPDX-FileCopyrightText:
// 2022 Nguyen Dao
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
module ConfigFSM (CLK, WriteData, WriteStrobe, Reset, FrameAddressRegister, LongFrameStrobe, RowSelect);
parameter NumberOfRows = 12;
parameter RowSelectWidth = 5;
parameter FrameBitsPerRow = 32;
parameter desync_flag = 20;
input CLK;
input [31:0] WriteData;
input WriteStrobe;
input Reset;
output reg [FrameBitsPerRow-1:0] FrameAddressRegister;
output reg LongFrameStrobe = 0;
output reg [RowSelectWidth-1:0] RowSelect;
reg FrameStrobe = 0;
//signal FrameShiftState : integer range 0 to (NumberOfRows + 2);
reg [4:0] FrameShiftState = 0;
//FSM
reg [1:0] state = 0;
reg old_reset;
always @ (posedge CLK) begin : P_FSM
old_reset <= Reset;
FrameStrobe <= 1'b0;
// we only activate the configuration after detecting a 32-bit aligned pattern "x"FAB0_FAB1"
// this allows placing the com-port header into the file and we can use the same file for parallel or UART configuration
// this also allows us to place whatever metadata, the only point to remeber is that the pattern/file needs to be 4-byte padded in the header
if ((old_reset == 1'b0) && (Reset == 1'b1)) begin // reset all on ComActive posedge
state <= 0;
FrameShiftState <= 0;
end else begin
case(state)
0: begin // unsynched
if(WriteStrobe == 1'b1) begin // if writing enabled
if (WriteData == 32'hFAB0_FAB1) begin // fire only after seeing pattern 0xFAB0_FAB1
state <= 1; //go to synched state
end
end
end
1: begin // SyncState read header
if(WriteStrobe == 1'b1) begin// if writing enabled
if(WriteData[desync_flag] == 1'b1) begin // desync
state <= 0; //desynced
end else begin
FrameAddressRegister <= WriteData;
FrameShiftState <= NumberOfRows ;
state <= 2; //writing frame data
end
end
end
2: begin
if(WriteStrobe == 1'b1) begin// if writing enabled
FrameShiftState <= FrameShiftState -1 ;
if(FrameShiftState == 1) begin // on last frame
FrameStrobe <= 1'b1; //trigger FrameStrobe
state <= 1; // we go to synched state waiting for next frame or desync
end
end
end
endcase
end
end
always @ (*) begin
if(WriteStrobe) begin // if writing active
RowSelect = FrameShiftState; // we write the frame
end else begin
RowSelect = {RowSelectWidth{1'b1}}; //otherwise, we write an invalid frame
end
end
reg oldFrameStrobe = 0;
always @ (posedge CLK) begin : P_StrobeREG
oldFrameStrobe <= FrameStrobe;
LongFrameStrobe <= (FrameStrobe || oldFrameStrobe);
end//CLK
endmodule