Initial commit
This commit is contained in:
199
LICENSE
Normal file
199
LICENSE
Normal file
@@ -0,0 +1,199 @@
|
||||
CERN Open Hardware Licence Version 2 - Permissive
|
||||
|
||||
|
||||
Preamble
|
||||
|
||||
CERN has developed this licence to promote collaboration among
|
||||
hardware designers and to provide a legal tool which supports the
|
||||
freedom to use, study, modify, share and distribute hardware designs
|
||||
and products based on those designs. Version 2 of the CERN Open
|
||||
Hardware Licence comes in three variants: this licence, CERN-OHL-P
|
||||
(permissive); and two reciprocal licences: CERN-OHL-W (weakly
|
||||
reciprocal) and CERN-OHL-S (strongly reciprocal).
|
||||
|
||||
The CERN-OHL-P is copyright CERN 2020. Anyone is welcome to use it, in
|
||||
unmodified form only.
|
||||
|
||||
Use of this Licence does not imply any endorsement by CERN of any
|
||||
Licensor or their designs nor does it imply any involvement by CERN in
|
||||
their development.
|
||||
|
||||
|
||||
1 Definitions
|
||||
|
||||
1.1 'Licence' means this CERN-OHL-P.
|
||||
|
||||
1.2 'Source' means information such as design materials or digital
|
||||
code which can be applied to Make or test a Product or to
|
||||
prepare a Product for use, Conveyance or sale, regardless of its
|
||||
medium or how it is expressed. It may include Notices.
|
||||
|
||||
1.3 'Covered Source' means Source that is explicitly made available
|
||||
under this Licence.
|
||||
|
||||
1.4 'Product' means any device, component, work or physical object,
|
||||
whether in finished or intermediate form, arising from the use,
|
||||
application or processing of Covered Source.
|
||||
|
||||
1.5 'Make' means to create or configure something, whether by
|
||||
manufacture, assembly, compiling, loading or applying Covered
|
||||
Source or another Product or otherwise.
|
||||
|
||||
1.6 'Notice' means copyright, acknowledgement and trademark notices,
|
||||
references to the location of any Notices, modification notices
|
||||
(subsection 3.3(b)) and all notices that refer to this Licence
|
||||
and to the disclaimer of warranties that are included in the
|
||||
Covered Source.
|
||||
|
||||
1.7 'Licensee' or 'You' means any person exercising rights under
|
||||
this Licence.
|
||||
|
||||
1.8 'Licensor' means a person who creates Source or modifies Covered
|
||||
Source and subsequently Conveys the resulting Covered Source
|
||||
under the terms and conditions of this Licence. A person may be
|
||||
a Licensee and a Licensor at the same time.
|
||||
|
||||
1.9 'Convey' means to communicate to the public or distribute.
|
||||
|
||||
|
||||
2 Applicability
|
||||
|
||||
2.1 This Licence governs the use, copying, modification, Conveying
|
||||
of Covered Source and Products, and the Making of Products. By
|
||||
exercising any right granted under this Licence, You irrevocably
|
||||
accept these terms and conditions.
|
||||
|
||||
2.2 This Licence is granted by the Licensor directly to You, and
|
||||
shall apply worldwide and without limitation in time.
|
||||
|
||||
2.3 You shall not attempt to restrict by contract or otherwise the
|
||||
rights granted under this Licence to other Licensees.
|
||||
|
||||
2.4 This Licence is not intended to restrict fair use, fair dealing,
|
||||
or any other similar right.
|
||||
|
||||
|
||||
3 Copying, Modifying and Conveying Covered Source
|
||||
|
||||
3.1 You may copy and Convey verbatim copies of Covered Source, in
|
||||
any medium, provided You retain all Notices.
|
||||
|
||||
3.2 You may modify Covered Source, other than Notices.
|
||||
|
||||
You may only delete Notices if they are no longer applicable to
|
||||
the corresponding Covered Source as modified by You and You may
|
||||
add additional Notices applicable to Your modifications.
|
||||
|
||||
3.3 You may Convey modified Covered Source (with the effect that You
|
||||
shall also become a Licensor) provided that You:
|
||||
|
||||
a) retain Notices as required in subsection 3.2; and
|
||||
|
||||
b) add a Notice to the modified Covered Source stating that You
|
||||
have modified it, with the date and brief description of how
|
||||
You have modified it.
|
||||
|
||||
3.4 You may Convey Covered Source or modified Covered Source under
|
||||
licence terms which differ from the terms of this Licence
|
||||
provided that You:
|
||||
|
||||
a) comply at all times with subsection 3.3; and
|
||||
|
||||
b) provide a copy of this Licence to anyone to whom You
|
||||
Convey Covered Source or modified Covered Source.
|
||||
|
||||
|
||||
4 Making and Conveying Products
|
||||
|
||||
You may Make Products, and/or Convey them, provided that You ensure
|
||||
that the recipient of the Product has access to any Notices applicable
|
||||
to the Product.
|
||||
|
||||
|
||||
5 DISCLAIMER AND LIABILITY
|
||||
|
||||
5.1 DISCLAIMER OF WARRANTY -- The Covered Source and any Products
|
||||
are provided 'as is' and any express or implied warranties,
|
||||
including, but not limited to, implied warranties of
|
||||
merchantability, of satisfactory quality, non-infringement of
|
||||
third party rights, and fitness for a particular purpose or use
|
||||
are disclaimed in respect of any Source or Product to the
|
||||
maximum extent permitted by law. The Licensor makes no
|
||||
representation that any Source or Product does not or will not
|
||||
infringe any patent, copyright, trade secret or other
|
||||
proprietary right. The entire risk as to the use, quality, and
|
||||
performance of any Source or Product shall be with You and not
|
||||
the Licensor. This disclaimer of warranty is an essential part
|
||||
of this Licence and a condition for the grant of any rights
|
||||
granted under this Licence.
|
||||
|
||||
5.2 EXCLUSION AND LIMITATION OF LIABILITY -- The Licensor shall, to
|
||||
the maximum extent permitted by law, have no liability for
|
||||
direct, indirect, special, incidental, consequential, exemplary,
|
||||
punitive or other damages of any character including, without
|
||||
limitation, procurement of substitute goods or services, loss of
|
||||
use, data or profits, or business interruption, however caused
|
||||
and on any theory of contract, warranty, tort (including
|
||||
negligence), product liability or otherwise, arising in any way
|
||||
in relation to the Covered Source, modified Covered Source
|
||||
and/or the Making or Conveyance of a Product, even if advised of
|
||||
the possibility of such damages, and You shall hold the
|
||||
Licensor(s) free and harmless from any liability, costs,
|
||||
damages, fees and expenses, including claims by third parties,
|
||||
in relation to such use.
|
||||
|
||||
|
||||
6 Patents
|
||||
|
||||
6.1 Subject to the terms and conditions of this Licence, each
|
||||
Licensor hereby grants to You a perpetual, worldwide,
|
||||
non-exclusive, no-charge, royalty-free, irrevocable (except as
|
||||
stated in this section 6, or where terminated by the Licensor
|
||||
for cause) patent licence to Make, have Made, use, offer to
|
||||
sell, sell, import, and otherwise transfer the Covered Source
|
||||
and Products, where such licence applies only to those patent
|
||||
claims licensable by such Licensor that are necessarily
|
||||
infringed by exercising rights under the Covered Source as
|
||||
Conveyed by that Licensor.
|
||||
|
||||
6.2 If You institute patent litigation against any entity (including
|
||||
a cross-claim or counterclaim in a lawsuit) alleging that the
|
||||
Covered Source or a Product constitutes direct or contributory
|
||||
patent infringement, or You seek any declaration that a patent
|
||||
licensed to You under this Licence is invalid or unenforceable
|
||||
then any rights granted to You under this Licence shall
|
||||
terminate as of the date such process is initiated.
|
||||
|
||||
|
||||
7 General
|
||||
|
||||
7.1 If any provisions of this Licence are or subsequently become
|
||||
invalid or unenforceable for any reason, the remaining
|
||||
provisions shall remain effective.
|
||||
|
||||
7.2 You shall not use any of the name (including acronyms and
|
||||
abbreviations), image, or logo by which the Licensor or CERN is
|
||||
known, except where needed to comply with section 3, or where
|
||||
the use is otherwise allowed by law. Any such permitted use
|
||||
shall be factual and shall not be made so as to suggest any kind
|
||||
of endorsement or implication of involvement by the Licensor or
|
||||
its personnel.
|
||||
|
||||
7.3 CERN may publish updated versions and variants of this Licence
|
||||
which it considers to be in the spirit of this version, but may
|
||||
differ in detail to address new problems or concerns. New
|
||||
versions will be published with a unique version number and a
|
||||
variant identifier specifying the variant. If the Licensor has
|
||||
specified that a given variant applies to the Covered Source
|
||||
without specifying a version, You may treat that Covered Source
|
||||
as being released under any version of the CERN-OHL with that
|
||||
variant. If no variant is specified, the Covered Source shall be
|
||||
treated as being released under CERN-OHL-S. The Licensor may
|
||||
also specify that the Covered Source is subject to a specific
|
||||
version of the CERN-OHL or any later version in which case You
|
||||
may apply this or any later version of CERN-OHL with the same
|
||||
variant identifier published by CERN.
|
||||
|
||||
7.4 This Licence shall not be enforceable except by a Licensor
|
||||
acting as such, and third party beneficiary rights are
|
||||
specifically excluded.
|
||||
79
constrs/default.xdc
Normal file
79
constrs/default.xdc
Normal file
@@ -0,0 +1,79 @@
|
||||
# Controller clock
|
||||
create_clock -period 10.000 -name CLK -waveform {0.000 5.000} [get_ports CLK]
|
||||
|
||||
set_clock_latency 0.500 [all_clocks]
|
||||
|
||||
set_property PACKAGE_PIN AF11 [get_ports AEROUT_ADDR_T[0]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AEROUT_ADDR_T[0]]
|
||||
set_property PACKAGE_PIN AG11 [get_ports AEROUT_ADDR_F[0]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AEROUT_ADDR_F[0]]
|
||||
|
||||
set_property PACKAGE_PIN AH12 [get_ports AEROUT_ADDR_T[1]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AEROUT_ADDR_T[1]]
|
||||
set_property PACKAGE_PIN J11 [get_ports AEROUT_ADDR_F[1]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AEROUT_ADDR_F[1]]
|
||||
|
||||
set_property PACKAGE_PIN J10 [get_ports AEROUT_ADDR_T[2]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AEROUT_ADDR_T[2]]
|
||||
set_property PACKAGE_PIN K13 [get_ports AEROUT_ADDR_F[2]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AEROUT_ADDR_F[2]]
|
||||
|
||||
set_property PACKAGE_PIN K12 [get_ports AEROUT_ADDR_T[3]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AEROUT_ADDR_T[3]]
|
||||
set_property PACKAGE_PIN H11 [get_ports AEROUT_ADDR_F[3]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AEROUT_ADDR_F[3]]
|
||||
|
||||
set_property PACKAGE_PIN G10 [get_ports AEROUT_ADDR_T[4]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AEROUT_ADDR_T[4]]
|
||||
set_property PACKAGE_PIN F12 [get_ports AEROUT_ADDR_F[4]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AEROUT_ADDR_F[4]]
|
||||
|
||||
set_property PACKAGE_PIN AC12 [get_ports AEROUT_ADDR_T[5]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AEROUT_ADDR_T[5]]
|
||||
set_property PACKAGE_PIN AD12 [get_ports AEROUT_ADDR_F[5]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AEROUT_ADDR_F[5]]
|
||||
|
||||
set_property PACKAGE_PIN AE10 [get_ports AEROUT_ADDR_T[6]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AEROUT_ADDR_T[6]]
|
||||
set_property PACKAGE_PIN AF10 [get_ports AEROUT_ADDR_F[6]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AEROUT_ADDR_F[6]]
|
||||
|
||||
set_property PACKAGE_PIN AD11 [get_ports AEROUT_ADDR_T[7]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AEROUT_ADDR_T[7]]
|
||||
set_property PACKAGE_PIN AD10 [get_ports AEROUT_ADDR_F[7]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AEROUT_ADDR_F[7]]
|
||||
|
||||
set_property PACKAGE_PIN AA11 [get_ports AEROUT_ADDR_T[8]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AEROUT_ADDR_T[8]]
|
||||
set_property PACKAGE_PIN AA10 [get_ports AEROUT_ADDR_F[8]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AEROUT_ADDR_F[8]]
|
||||
|
||||
set_property PACKAGE_PIN AE12 [get_ports AEROUT_ACK]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AEROUT_ACK]
|
||||
|
||||
set_property PACKAGE_PIN C3 [get_ports CLK]
|
||||
set_property IOSTANDARD LVCMOS18 [get_ports CLK]
|
||||
|
||||
set_property PACKAGE_PIN AF12 [get_ports RSTN_O]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports RSTN_O]
|
||||
|
||||
set_property PACKAGE_PIN AH10 [get_ports AERIN_REQ]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AERIN_REQ]
|
||||
|
||||
set_property PACKAGE_PIN AG10 [get_ports AERIN_ACK]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AERIN_ACK]
|
||||
|
||||
set_property PACKAGE_PIN H12 [get_ports AERIN_ADDR[4]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AERIN_ADDR[4]]
|
||||
|
||||
set_property PACKAGE_PIN E10 [get_ports AERIN_ADDR[3]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AERIN_ADDR[3]]
|
||||
|
||||
set_property PACKAGE_PIN D10 [get_ports AERIN_ADDR[2]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AERIN_ADDR[2]]
|
||||
|
||||
set_property PACKAGE_PIN C11 [get_ports AERIN_ADDR[1]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AERIN_ADDR[1]]
|
||||
|
||||
set_property PACKAGE_PIN B10 [get_ports AERIN_ADDR[0]]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports AERIN_ADDR[0]]
|
||||
131074
iladata.csv
Normal file
131074
iladata.csv
Normal file
File diff suppressed because it is too large
Load Diff
BIN
iladata.ila
Normal file
BIN
iladata.ila
Normal file
Binary file not shown.
0
sim/mem_stim_db.sv
Normal file
0
sim/mem_stim_db.sv
Normal file
67
sim/mem_stim_tb.sv
Normal file
67
sim/mem_stim_tb.sv
Normal file
@@ -0,0 +1,67 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 02/20/2026 02:02:47 PM
|
||||
// Design Name:
|
||||
// Module Name: mem_stim_tb
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`define CLK_HALF_PERIOD 2
|
||||
|
||||
module mem_stim_tb(
|
||||
|
||||
);
|
||||
|
||||
logic CLK;
|
||||
logic RST_N;
|
||||
logic ACK;
|
||||
logic [8:0] ADDR_T;
|
||||
logic [8:0] ADDR_F;
|
||||
wire END_SIG;
|
||||
|
||||
initial begin
|
||||
CLK = 1'b0;
|
||||
forever #(`CLK_HALF_PERIOD) CLK = ~CLK;
|
||||
end
|
||||
|
||||
initial begin
|
||||
RST_N = 1'b0;
|
||||
#(4 * `CLK_HALF_PERIOD);
|
||||
RST_N = 1'b1;
|
||||
#(20 * `CLK_HALF_PERIOD);
|
||||
end
|
||||
|
||||
mem_stim #(
|
||||
.DATA_WIDTH(9)
|
||||
) ut (
|
||||
.clk(CLK),
|
||||
.rst_n(RST_N),
|
||||
.restart(~RST_N),
|
||||
.ack(ACK),
|
||||
.addr_t(ADDR_T),
|
||||
.addr_f(ADDR_F),
|
||||
.done(END_SIG)
|
||||
);
|
||||
|
||||
autoack auto_ack (
|
||||
.CLK(CLK),
|
||||
.RST(!RST_N),
|
||||
.OUTPUT_BITS_ONION_p(ADDR_T),
|
||||
.OUTPUT_BITS_ONION_n(ADDR_F),
|
||||
.OUTPUT_BITS_ONION_A_AO(ACK)
|
||||
);
|
||||
|
||||
endmodule
|
||||
163
sim/olla_testack.sv
Normal file
163
sim/olla_testack.sv
Normal file
@@ -0,0 +1,163 @@
|
||||
`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
|
||||
65
sim/stimulus_gen_tb.sv
Normal file
65
sim/stimulus_gen_tb.sv
Normal file
@@ -0,0 +1,65 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 02/16/2026 05:49:17 PM
|
||||
// Design Name:
|
||||
// Module Name: stimulus_gen_tb
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`define CLK_HALF_PERIOD 2
|
||||
|
||||
module stimulus_gen_tb(
|
||||
|
||||
);
|
||||
|
||||
logic CLK;
|
||||
logic RST;
|
||||
logic ACK;
|
||||
logic REQ;
|
||||
logic [4:0] ADDR;
|
||||
wire END_SIG;
|
||||
|
||||
initial begin
|
||||
CLK = 1'b0;
|
||||
forever #(`CLK_HALF_PERIOD) CLK = ~CLK;
|
||||
end
|
||||
|
||||
initial begin
|
||||
RST = 1'b1;
|
||||
#(4 * `CLK_HALF_PERIOD);
|
||||
RST = 1'b0;
|
||||
#(20 * `CLK_HALF_PERIOD);
|
||||
end
|
||||
|
||||
always_ff @(posedge CLK)
|
||||
begin
|
||||
if (REQ) begin
|
||||
ACK <= 1'b1;
|
||||
end else begin
|
||||
ACK <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
stimulus_gen #() ut (
|
||||
.CLK_I(CLK),
|
||||
.RST_I(RST),
|
||||
.REQ_O(REQ),
|
||||
.ACK_I(ACK),
|
||||
.ADDR_O(ADDR),
|
||||
.END_O(END_SIG)
|
||||
);
|
||||
|
||||
endmodule
|
||||
70
sim/top_interface_tb.sv
Normal file
70
sim/top_interface_tb.sv
Normal file
@@ -0,0 +1,70 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 02/16/2026 07:33:07 PM
|
||||
// Design Name:
|
||||
// Module Name: top_interface_tb
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`define CLK_HALF_PERIOD 2
|
||||
|
||||
module top_interface_tb(
|
||||
|
||||
);
|
||||
logic CLK;
|
||||
logic RSTN;
|
||||
logic AERIN_REQ;
|
||||
logic AERIN_ACK;
|
||||
logic [4:0] AERIN_ADDR;
|
||||
|
||||
logic AEROUT_ACK;
|
||||
logic [8:0] AEROUT_ADDR_T;
|
||||
logic [8:0] AEROUT_ADDR_F;
|
||||
|
||||
initial begin
|
||||
CLK = 1'b0;
|
||||
forever #(`CLK_HALF_PERIOD) CLK = ~CLK;
|
||||
end
|
||||
|
||||
assign RST = !RSTN;
|
||||
|
||||
top_interface #() ut (
|
||||
.CLK(CLK),
|
||||
.RSTN_O(RSTN),
|
||||
.AERIN_REQ(AERIN_REQ),
|
||||
.AERIN_ADDR(AERIN_ADDR),
|
||||
.AERIN_ACK(AERIN_ACK),
|
||||
.AEROUT_ACK(AEROUT_ACK),
|
||||
.AEROUT_ADDR_T(AEROUT_ADDR_T),
|
||||
.AEROUT_ADDR_F(AEROUT_ADDR_F)
|
||||
);
|
||||
|
||||
autoack auto_ack (
|
||||
.CLK(CLK),
|
||||
.RST(RST),
|
||||
.OUTPUT_BITS_ONION_p(AEROUT_ADDR_T),
|
||||
.OUTPUT_BITS_ONION_n(AEROUT_ADDR_F),
|
||||
.OUTPUT_BITS_ONION_A_AO(AEROUT_ACK)
|
||||
);
|
||||
|
||||
stimulus_gen #() stim (
|
||||
.CLK_I(CLK),
|
||||
.RST_I(RST),
|
||||
.REQ_O(AERIN_REQ),
|
||||
.ACK_I(AERIN_ACK),
|
||||
.ADDR_O(AERIN_ADDR)
|
||||
);
|
||||
endmodule
|
||||
154
src/mem_stim.sv
Normal file
154
src/mem_stim.sv
Normal file
@@ -0,0 +1,154 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 02/17/2026 05:28:09 PM
|
||||
// Design Name:
|
||||
// Module Name: mem_stim
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module mem_stim #(
|
||||
parameter int DATA_WIDTH = 9,
|
||||
parameter string MEM_FILE = "stim.mem",
|
||||
parameter int MAX_EVENTS = 1024
|
||||
)(
|
||||
input logic clk,
|
||||
input logic rst_n,
|
||||
input logic restart,
|
||||
|
||||
input logic ack,
|
||||
output logic [DATA_WIDTH-1:0] addr_t,
|
||||
output logic [DATA_WIDTH-1:0] addr_f,
|
||||
|
||||
output logic done
|
||||
);
|
||||
|
||||
typedef enum logic [2:0] {
|
||||
S_LOAD,
|
||||
S_WAIT,
|
||||
S_SEND,
|
||||
S_WAIT_ACK_HIGH,
|
||||
S_WAIT_ACK_LOW,
|
||||
S_DONE
|
||||
} state_t;
|
||||
|
||||
state_t state;
|
||||
logic [31-DATA_WIDTH:0] delay_counter;
|
||||
wire [31:0] mem_data;
|
||||
wire [DATA_WIDTH-1:0] event_addr;
|
||||
wire [31-DATA_WIDTH:0] DELAY_LIMIT;
|
||||
reg [11:0] mem_addr;
|
||||
wire test;
|
||||
|
||||
assign test = (mem_data != 32'hFFFF_FFFF);
|
||||
|
||||
always_ff @(posedge clk or negedge rst_n)
|
||||
begin
|
||||
if (!rst_n || restart) begin
|
||||
state <= S_LOAD;
|
||||
delay_counter <= {32-DATA_WIDTH{1'b0}};
|
||||
addr_t <= {DATA_WIDTH{1'b0}};
|
||||
addr_f <= {DATA_WIDTH{1'b0}};
|
||||
done <= 1'b0;
|
||||
mem_addr <= 12'b0;
|
||||
end else begin
|
||||
delay_counter <= delay_counter + 1;
|
||||
|
||||
case (state)
|
||||
S_LOAD: begin
|
||||
addr_t <= {DATA_WIDTH{1'b0}};
|
||||
addr_f <= {DATA_WIDTH{1'b0}};
|
||||
done <= 1'b0;
|
||||
|
||||
if (mem_addr < MAX_EVENTS) begin
|
||||
state <= S_WAIT;
|
||||
end else begin
|
||||
state <= S_DONE;
|
||||
end
|
||||
end
|
||||
|
||||
S_WAIT: begin
|
||||
if (mem_data == 32'hFFFF_FFFF)
|
||||
state <= S_DONE;
|
||||
else if (delay_counter >= DELAY_LIMIT)
|
||||
state <= S_SEND;
|
||||
end
|
||||
|
||||
S_SEND: begin
|
||||
addr_t <= event_addr;
|
||||
addr_f <= ~event_addr;
|
||||
state <= S_WAIT_ACK_HIGH;
|
||||
end
|
||||
|
||||
S_WAIT_ACK_HIGH: begin
|
||||
if (ack) begin
|
||||
state <= S_WAIT_ACK_LOW;
|
||||
addr_t <= {DATA_WIDTH{1'b0}};
|
||||
addr_f <= {DATA_WIDTH{1'b0}};
|
||||
end
|
||||
end
|
||||
|
||||
S_WAIT_ACK_LOW: begin
|
||||
if (!ack) begin
|
||||
mem_addr <= mem_addr + 1;
|
||||
state <= S_LOAD;
|
||||
end
|
||||
end
|
||||
|
||||
S_DONE: begin
|
||||
done <= 1'b1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
assign event_addr = mem_data[DATA_WIDTH-1:0];
|
||||
assign DELAY_LIMIT = mem_data[31:DATA_WIDTH];
|
||||
|
||||
BRAM_stim #(.MEM_FILE(MEM_FILE)) mem (
|
||||
.clk(clk),
|
||||
.A(mem_addr),
|
||||
.Q(mem_data)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
module BRAM_stim #(
|
||||
parameter string MEM_FILE = "stim.mem"
|
||||
)(
|
||||
input logic clk,
|
||||
|
||||
input logic [11:0] A,
|
||||
output logic [31:0] Q
|
||||
);
|
||||
|
||||
reg [31:0] BRAM_stim[4095:0];
|
||||
reg [31:0] Qr;
|
||||
|
||||
assign Q = Qr;
|
||||
|
||||
initial begin
|
||||
for (int i = 0; i < 4096; i++) begin
|
||||
BRAM_stim[i] = 32'b0;
|
||||
end
|
||||
$readmemh(MEM_FILE, BRAM_stim);
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
Qr <= BRAM_stim[A];
|
||||
end
|
||||
|
||||
endmodule
|
||||
80
src/olla_in.sv
Normal file
80
src/olla_in.sv
Normal file
@@ -0,0 +1,80 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 02/16/2026 04:05:38 PM
|
||||
// Design Name:
|
||||
// Module Name: olla_in
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module olla_in(
|
||||
input logic CLK_I,
|
||||
input logic RST_I,
|
||||
|
||||
input logic AERIN_REQ,
|
||||
output logic AERIN_ACK
|
||||
);
|
||||
|
||||
localparam int COUNTER_WIDTH = 27;
|
||||
localparam int COUNTER_LIMIT = 25 - 1;
|
||||
|
||||
typedef enum logic [1:0] {
|
||||
S_WAIT_REQ,
|
||||
S_TIMER_WAIT,
|
||||
S_SEND_ACK
|
||||
} state_t;
|
||||
|
||||
state_t state, next_state;
|
||||
|
||||
logic [COUNTER_WIDTH-1:0] counter_reg;
|
||||
|
||||
always_ff @(posedge CLK_I)
|
||||
begin
|
||||
if (RST_I) state <= S_WAIT_REQ;
|
||||
else state <= next_state;
|
||||
end
|
||||
|
||||
always_ff @(posedge CLK_I)
|
||||
begin
|
||||
if (RST_I) begin
|
||||
counter_reg <= '0;
|
||||
end
|
||||
else begin
|
||||
if (state == S_TIMER_WAIT) begin
|
||||
if (counter_reg == COUNTER_LIMIT)
|
||||
counter_reg <= '0;
|
||||
else
|
||||
counter_reg <= counter_reg + 1;
|
||||
end
|
||||
else
|
||||
counter_reg <= '0;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
case (state)
|
||||
S_WAIT_REQ: if (AERIN_REQ) next_state = S_TIMER_WAIT;
|
||||
else next_state = S_WAIT_REQ;
|
||||
S_TIMER_WAIT: if (counter_reg == COUNTER_LIMIT) next_state = S_SEND_ACK;
|
||||
else next_state = S_TIMER_WAIT;
|
||||
S_SEND_ACK: next_state = S_WAIT_REQ;
|
||||
default: next_state = S_WAIT_REQ;
|
||||
endcase
|
||||
end
|
||||
|
||||
assign AERIN_ACK = (state == S_SEND_ACK) ? 1'b1 : 1'b0;
|
||||
|
||||
endmodule
|
||||
3
src/stim.mem
Normal file
3
src/stim.mem
Normal file
@@ -0,0 +1,3 @@
|
||||
000000f0
|
||||
0000f050
|
||||
ffffffff
|
||||
125
src/stimulus_gen.sv
Normal file
125
src/stimulus_gen.sv
Normal file
@@ -0,0 +1,125 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 02/16/2026 05:08:08 PM
|
||||
// Design Name:
|
||||
// Module Name: stimulus_gen
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module stimulus_gen(
|
||||
input logic CLK_I,
|
||||
input logic RST_I,
|
||||
|
||||
input logic ACK_I,
|
||||
output logic REQ_O,
|
||||
output logic END_O,
|
||||
output logic [4:0] ADDR_O
|
||||
);
|
||||
|
||||
typedef enum logic [2:0] {
|
||||
S_IDLE,
|
||||
S_SEND_REQ,
|
||||
S_WAIT_ACK_HIGH,
|
||||
S_WAIT_ACK_LOW,
|
||||
S_WAIT_DELAY,
|
||||
S_END
|
||||
} state_t;
|
||||
|
||||
state_t state, next_state;
|
||||
|
||||
logic [4:0] neuron_counter;
|
||||
logic [7:0] event_counter;
|
||||
logic [27:0] delay_counter;
|
||||
|
||||
localparam int DELAY_LIMIT = 270;
|
||||
localparam int EVENT_LIMIT = 5;
|
||||
|
||||
assign END_O = state == S_END;
|
||||
|
||||
always_ff @(posedge CLK_I)
|
||||
begin
|
||||
if (RST_I) state <= S_IDLE;
|
||||
else state <= next_state;
|
||||
end
|
||||
|
||||
always_comb
|
||||
begin
|
||||
case (state)
|
||||
S_IDLE: next_state = S_SEND_REQ;
|
||||
S_SEND_REQ: if (ACK_I) next_state = S_WAIT_ACK_LOW;
|
||||
else next_state = S_WAIT_ACK_HIGH;
|
||||
S_WAIT_ACK_HIGH: if (ACK_I) next_state = S_WAIT_ACK_LOW;
|
||||
else next_state = S_WAIT_ACK_HIGH;
|
||||
S_WAIT_ACK_LOW: if (!ACK_I) next_state = S_WAIT_DELAY;
|
||||
else next_state = S_WAIT_ACK_LOW;
|
||||
S_WAIT_DELAY: if (ADDR_O == 5'd31 && event_counter == EVENT_LIMIT) next_state = S_END;
|
||||
else if (delay_counter == DELAY_LIMIT) next_state = S_IDLE;
|
||||
else next_state = S_WAIT_DELAY;
|
||||
S_END: next_state = S_END;
|
||||
default: next_state = S_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
always_ff @(posedge CLK_I)
|
||||
begin
|
||||
if (RST_I) begin
|
||||
REQ_O <= 1'b0;
|
||||
ADDR_O <= 5'b0;
|
||||
event_counter <= 8'b0;
|
||||
delay_counter <= 28'd0;
|
||||
neuron_counter <= 5'd0;
|
||||
end
|
||||
else begin
|
||||
case (state)
|
||||
S_SEND_REQ: begin
|
||||
REQ_O <= 1'b1;
|
||||
end
|
||||
|
||||
S_WAIT_ACK_HIGH: begin
|
||||
// Wait for receiver to acknowledge
|
||||
if (ACK_I) begin
|
||||
REQ_O <= 1'b0; // drop REQ
|
||||
end
|
||||
end
|
||||
|
||||
S_WAIT_ACK_LOW: begin
|
||||
// Wait until ACK drops again (handshake complete)
|
||||
if (!ACK_I) begin
|
||||
event_counter <= event_counter + 1'b1;
|
||||
delay_counter <= 28'd0;
|
||||
end
|
||||
end
|
||||
|
||||
S_WAIT_DELAY: begin
|
||||
// Optional delay between events (prevents back-to-back firing)
|
||||
if (event_counter == EVENT_LIMIT) begin
|
||||
if (ADDR_O < 6'd31) begin
|
||||
ADDR_O <= ADDR_O + 1'b1;
|
||||
event_counter <= 8'd0;
|
||||
end
|
||||
end
|
||||
|
||||
if (delay_counter == DELAY_LIMIT) begin
|
||||
delay_counter <= 28'd0;
|
||||
end else begin
|
||||
delay_counter <= delay_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
102
src/top_interface.sv
Normal file
102
src/top_interface.sv
Normal file
@@ -0,0 +1,102 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 02/16/2026 05:01:17 PM
|
||||
// Design Name:
|
||||
// Module Name: top_interface
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool Versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module top_interface(
|
||||
input logic CLK,
|
||||
output logic RSTN_O,
|
||||
|
||||
input logic AERIN_REQ,
|
||||
input logic [4:0] AERIN_ADDR,
|
||||
output logic AERIN_ACK,
|
||||
|
||||
input logic AEROUT_ACK,
|
||||
output logic [8:0] AEROUT_ADDR_T,
|
||||
output logic [8:0] AEROUT_ADDR_F
|
||||
);
|
||||
|
||||
wire [4:0] AERIN_ADDR_debug;
|
||||
wire [8:0] AEROUT_ADDR_T_debug;
|
||||
wire [8:0] AEROUT_ADDR_F_debug;
|
||||
wire AEROUT_ACK_debug, AERIN_REQ_debug, AERIN_ACK_debug;
|
||||
|
||||
wire RST;
|
||||
wire END_SIG;
|
||||
wire AERIN_REQ_N, AERIN_ACK_N;
|
||||
|
||||
localparam int RESET_LIMIT = 27;
|
||||
|
||||
assign AERIN_REQ_N = !AERIN_REQ;
|
||||
assign AERIN_REQ_DEBUG = AERIN_REQ;
|
||||
assign AERIN_ACK_DEBUG = !AERIN_ACK_N;
|
||||
assign AERIN_ACK = AERIN_ACK_DEBUG;
|
||||
assign AEROUT_ACK_debug = AEROUT_ACK;
|
||||
|
||||
logic [ 27:0] reset_counter = 28'd0;
|
||||
|
||||
always_ff @(posedge CLK)
|
||||
begin
|
||||
if (reset_counter != RESET_LIMIT) begin
|
||||
reset_counter <= reset_counter + 1;
|
||||
end else if (END_SIG) begin
|
||||
reset_counter <= 25'd0;
|
||||
end
|
||||
end
|
||||
|
||||
assign RSTN_O = !RST;
|
||||
assign RST = (reset_counter != RESET_LIMIT) ? 1'b1 : 1'b0;
|
||||
|
||||
mem_stim #(
|
||||
.DATA_WIDTH(5),
|
||||
.MEM_FILE("./stim.mem"),
|
||||
.MAX_EVENTS(1024)
|
||||
) stim (
|
||||
.clk(CLK_I),
|
||||
.rst_n(!RST),
|
||||
.restart(RST),
|
||||
.ack(AEROUT_ACK),
|
||||
.addr_t(AEROUT_ADDR_T_debug),
|
||||
.addr_f(AEROUT_ADDR_F_debug),
|
||||
.done(END_SIG)
|
||||
);
|
||||
assign AEROUT_ADDR_T = AEROUT_ADDR_T_debug;
|
||||
assign AEROUT_ADDR_F = AEROUT_ADDR_F_debug;
|
||||
assign AERIN_ADDR_debug = AERIN_ADDR;
|
||||
|
||||
olla_in #() AER_interface (
|
||||
.CLK_I(CLK),
|
||||
.RST_I(RST),
|
||||
.AERIN_REQ(AERIN_REQ_N),
|
||||
.AERIN_ACK(AERIN_ACK_N)
|
||||
);
|
||||
|
||||
ila_0 ila (
|
||||
.clk(CLK),
|
||||
.probe0(RST),
|
||||
.probe1(AEROUT_ACK_debug),
|
||||
.probe2(AEROUT_ADDR_T_debug),
|
||||
.probe3(AEROUT_ADDR_F_debug),
|
||||
.probe4(AERIN_REQ_debug),
|
||||
.probe5(AERIN_ACK_debug),
|
||||
.probe6(AERIN_ADDR_debug)
|
||||
);
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user