Files
OllaInterface/sim/olla_testack.sv

163 lines
6.1 KiB
Systemverilog
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 02/16/2026 08:28:02 PM
// Design Name:
// Module Name: olla_testack
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module autoack (
input logic CLK,
input logic RST,
input logic [8:0] OUTPUT_BITS_ONION_p,
input logic [8:0] OUTPUT_BITS_ONION_n,
output logic OUTPUT_BITS_ONION_A_AO
);
//---------------------------------------------------------
// Local Parameters
//---------------------------------------------------------
localparam int COUNTER_WIDTH = 27;
// Örnek: CLK = 25 MHz ise 25,000,000 çevrim 1 saniyedir.
// localparam int ONE_SEC_LIMIT = 25_000_000 - 1;
localparam int ONE_SEC_LIMIT = 5 - 1;
//---------------------------------------------------------
// Internal Signals
//---------------------------------------------------------
// FSM State Definitions
typedef enum logic [3:0] {
S_WAIT_DATA_BLANK, // Faz 1: Veri hatlarının ve ACK'nin 0 olmasını bekle.
S_DATA_LATCH, // Faz 2: Veri geldi, veriyi/adresi yakala.
S_TIMER_START, // LED zamanlayıcısını başlat (Sayacı sıfırla).
S_TIMER_WAIT, // LED açıkken 1 saniye bekle (ON Time).
S_LED_BLANK_WAIT, // LED kapalıyken 1 saniye bekle (OFF Time).
S_SEND_ACK, // Faz 3: ACK'yi '1' yap.
S_WAIT_DATA_BLANK_LOW, // Faz 4: Göndericinin veri hatlarını '0' çekmesini bekle.
S_ACK_LOW // Faz 5: ACK'yi '0' yap ve S_WAIT_DATA_BLANK'e dön.
} state_t;
state_t state, next_state;
logic [COUNTER_WIDTH-1:0] counter_reg;
//---------------------------------------------------------
// 1. Dual-Rail Veri Kontrolü
//---------------------------------------------------------
// 'data_arrived' sinyali: Data hatlarından herhangi biri '1' ise veri gelmiştir.
logic data_arrived;
assign data_arrived = |OUTPUT_BITS_ONION_p | |OUTPUT_BITS_ONION_n;
// 'data_is_blank' sinyali: Tüm data hatları '0' ise hat boş/temizdir.
logic data_is_blank;
assign data_is_blank = ~data_arrived;
//---------------------------------------------------------
// 2. Sequential Logic: Counter Register
//---------------------------------------------------------
always_ff @(posedge CLK)
begin
if (RST) begin
counter_reg <= '0;
end
else begin
// Counter Logic: Increments in S_TIMER_WAIT (LED ON time)
// OR S_LED_BLANK_WAIT (LED OFF time)
if (state == S_TIMER_WAIT || state == S_LED_BLANK_WAIT) begin
if (counter_reg == ONE_SEC_LIMIT)
counter_reg <= '0;
else
counter_reg <= counter_reg + 1;
end
// Reset counter when a new timer sequence starts
else if (state == S_TIMER_START)
counter_reg <= '0;
// Reset counter in other states if it's not already 0 (safety)
else if (counter_reg != '0 && state != S_TIMER_WAIT && state != S_LED_BLANK_WAIT)
counter_reg <= '0;
end
end
//---------------------------------------------------------
// 3. Sequential Logic: State Register
//---------------------------------------------------------
always_ff @(posedge CLK)
begin
if (RST) state <= S_WAIT_DATA_BLANK;
else state <= next_state;
end
//----------------------------------------------------------
// 4. Combinational Logic: Next State Determination (FSM)
//----------------------------------------------------------
always_comb begin
next_state = state;
case (state)
S_WAIT_DATA_BLANK: // Faz 1: Hatların boş olmasını bekle
if (data_arrived) // Veri geldiğinde (Dual-rail sinyalleri 0'dan farklı)
next_state = S_DATA_LATCH;
S_DATA_LATCH: // Faz 2: Veri geldi, zamanlayıcıyı başlat
next_state = S_TIMER_START;
S_TIMER_START: // LED ON süresini başlatmak için sayacı sıfırla
next_state = S_TIMER_WAIT;
S_TIMER_WAIT: // LED açıkken 1 saniye bekle
if (counter_reg == ONE_SEC_LIMIT)
next_state = S_LED_BLANK_WAIT; // LED'i söndürme süresine geç
S_LED_BLANK_WAIT: // LED kapalıyken 1 saniye bekle (Blink süresi)
if (counter_reg == ONE_SEC_LIMIT)
next_state = S_SEND_ACK; // ACK gönderme döngüsüne geç
S_SEND_ACK: // Faz 3: ACK'yi '1' yap
next_state = S_WAIT_DATA_BLANK_LOW;
S_WAIT_DATA_BLANK_LOW: // Faz 4: Göndericinin veri hatlarını '0' çekmesini bekle
if (data_is_blank) // Veri hatları boşaldı (tümü '0')
next_state = S_ACK_LOW;
S_ACK_LOW: // Faz 5: ACK'yi '0' yap
next_state = S_WAIT_DATA_BLANK;
default:
next_state = S_WAIT_DATA_BLANK;
endcase
end
//-----------------------------------------------------------
// 5. Combinational Logic: Output Generation
//-----------------------------------------------------------
always_comb begin
// Default değerler
OUTPUT_BITS_ONION_A_AO = 1'b0;
case (state)
S_SEND_ACK, S_WAIT_DATA_BLANK_LOW:
OUTPUT_BITS_ONION_A_AO = 1'b1;
default: ;
endcase
end
endmodule