| // 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 |