Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
X
x393
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
x393
Commits
860b1594
Commit
860b1594
authored
Jul 12, 2016
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
minor fixes
parent
05a118d9
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
22 additions
and
433 deletions
+22
-433
socket_command.py
cocotb/socket_command.py
+5
-6
x393_cocotb_server.py
cocotb/x393_cocotb_server.py
+3
-0
x393_dut.v
cocotb/x393_dut.v
+7
-408
x393interfaces.py
cocotb/x393interfaces.py
+5
-4
x393_mem.py
py393/x393_mem.py
+1
-14
x393_1_8_2.Doxyfile
x393_1_8_2.Doxyfile
+1
-1
No files found.
cocotb/socket_command.py
View file @
860b1594
...
@@ -15,6 +15,11 @@ from __future__ import print_function
...
@@ -15,6 +15,11 @@ from __future__ import print_function
#
#
# You should have received a copy of the GNU General Public License
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http:#www.gnu.org/licenses/>.
# along with this program. If not, see <http:#www.gnu.org/licenses/>.
@brief: Provides sockets-related functionality for both the simulation server
and tghe client. Server is linked to the Cocotb and custom modules and controls
the simulation, server is used to replace memory read/write functionality in the
target system
@author: Andrey Filippov
@author: Andrey Filippov
@copyright: 2016 Elphel, Inc.
@copyright: 2016 Elphel, Inc.
@license: GPLv3.0+
@license: GPLv3.0+
...
@@ -97,19 +102,13 @@ class x393Client():
...
@@ -97,19 +102,13 @@ class x393Client():
def
write
(
self
,
address
,
data
):
def
write
(
self
,
address
,
data
):
self
.
cmd
.
setWrite
([
address
,
data
])
self
.
cmd
.
setWrite
([
address
,
data
])
rslt
=
self
.
communicate
(
self
.
cmd
.
toJSON
())
rslt
=
self
.
communicate
(
self
.
cmd
.
toJSON
())
# print("write->",rslt)
def
waitIrq
(
self
,
irqMask
,
wait_ns
):
def
waitIrq
(
self
,
irqMask
,
wait_ns
):
self
.
cmd
.
setWait
([
irqMask
,
wait_ns
])
self
.
cmd
.
setWait
([
irqMask
,
wait_ns
])
rslt
=
self
.
communicate
(
self
.
cmd
.
toJSON
())
rslt
=
self
.
communicate
(
self
.
cmd
.
toJSON
())
# print("waitIrq->",rslt)
def
flush
(
self
):
def
flush
(
self
):
self
.
cmd
.
setFlush
()
self
.
cmd
.
setFlush
()
# print("flush->",self.communicate(self.cmd.toJSON()))
def
read
(
self
,
address
):
def
read
(
self
,
address
):
self
.
cmd
.
setRead
(
address
)
self
.
cmd
.
setRead
(
address
)
# print("read->args",self.cmd.getArgs())
rslt
=
self
.
communicate
(
self
.
cmd
.
toJSON
())
rslt
=
self
.
communicate
(
self
.
cmd
.
toJSON
())
#print("read->",rslt)
return
json
.
loads
(
rslt
)
return
json
.
loads
(
rslt
)
cocotb/x393_cocotb_server.py
View file @
860b1594
...
@@ -15,6 +15,9 @@ from __future__ import print_function
...
@@ -15,6 +15,9 @@ from __future__ import print_function
#
#
# You should have received a copy of the GNU General Public License
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http:#www.gnu.org/licenses/>.
# along with this program. If not, see <http:#www.gnu.org/licenses/>.
@brief: Simulation server for x393_dut.v top Verilog module.
Listens to the socket connection, accepts incoming commands, applies them
to the simulator and sends back data from the model.
@author: Andrey Filippov
@author: Andrey Filippov
@copyright: 2016 Elphel, Inc.
@copyright: 2016 Elphel, Inc.
@license: GPLv3.0+
@license: GPLv3.0+
...
...
cocotb/x393_dut.v
View file @
860b1594
...
@@ -2,15 +2,15 @@
...
@@ -2,15 +2,15 @@
* <b>Module:</b> x393_dut
* <b>Module:</b> x393_dut
* @file x393_dut.v
* @file x393_dut.v
* @date 2016-06-27
* @date 2016-06-27
* @author
eyesis
* @author
Andrey Filippov
*
*
* @brief Top DUT module for
trying c
ocotb
* @brief Top DUT module for
simulating x393 project with C
ocotb
* In
itially will include other simulation modules, leaving just AXI for communicating
* In
cludes instances of other Verilog simulation modules and I/O ports
*
with Cocotb
*
for interfacing with Python modules
*
*
* @copyright Copyright (c) 2016
<set up in Preferences-Verilog/VHDL Editor-Templates>
.
* @copyright Copyright (c) 2016
Elphel, Inc
.
*
*
* <b>License
</b>
* <b>License
:
</b>
*
*
* x393_dut.v is free software; you can redistribute it and/or modify
* x393_dut.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* it under the terms of the GNU General Public License as published by
...
@@ -1712,406 +1712,5 @@ simul_axi_hp_wr #(
...
@@ -1712,406 +1712,5 @@ simul_axi_hp_wr #(
assign
x393_i
.
ps7_i
.
FCLKCLK
=
{
4
{
CLK
}};
assign
x393_i
.
ps7_i
.
FCLKCLK
=
{
4
{
CLK
}};
assign
x393_i
.
ps7_i
.
FCLKRESETN
=
{
RST
,~
RST
,
RST
,~
RST
};
assign
x393_i
.
ps7_i
.
FCLKRESETN
=
{
RST
,~
RST
,
RST
,~
RST
};
//`define SHOW_TMP_TASKS
// Temporary
`ifdef
SHOW_TMP_TASKS
task
write_contol_register
;
input
[
29
:
0
]
reg_addr
;
// input integer reg_addr;
input
[
31
:
0
]
data
;
begin
axi_write_single_w
(
CONTROL_ADDR
+
reg_addr
,
data
)
;
end
endtask
task
read_contol_register
;
input
[
29
:
0
]
reg_addr
;
begin
read_and_wait_w
(
CONTROL_RBACK_ADDR
+
reg_addr
)
;
end
endtask
task
wait_read_queue_empty
;
begin
wait
(
~
rvalid
&&
rready
&&
(
rid
==
LAST_ARID
))
;
// nothing left in read queue?
SIMUL_AXI_FULL
<=
1'b0
;
end
endtask
task
axi_set_rd_lag
;
input
[
3
:
0
]
lag
;
begin
@
(
posedge
CLK
)
;
dutm0_xtra_rdlag
<=
lag
;
end
endtask
task
axi_set_b_lag
;
input
[
3
:
0
]
lag
;
begin
@
(
posedge
CLK
)
;
dutm0_xtra_blag
<=
lag
;
end
endtask
task
read_and_wait_w
;
input
[
29
:
0
]
address
;
begin
read_and_wait
(
{
address
,
2'b0
}
)
;
end
endtask
task
read_and_wait
;
input
[
31
:
0
]
address
;
begin
IRQ_EN
=
0
;
wait
(
CLK
)
;
while
(
!
MAIN_GO
)
begin
wait
(
!
CLK
)
;
wait
(
CLK
)
;
end
axi_read_addr_inner
(
GLOBAL_READ_ID
,
// id
address
&
32'hfffffffc
,
// addr
4'h0
,
// len - single
1
// burst type - increment
)
;
GLOBAL_READ_ID
<=
GLOBAL_READ_ID
+
1
;
wait
(
!
CLK
&&
rvalid
&&
rready
)
;
wait
(
CLK
)
;
registered_rdata
<=
rdata
;
wait
(
!
CLK
)
;
// registered_rdata should be valid on exit
IRQ_EN
=
1
;
if
(
IRQS
)
begin
@
(
posedge
CLK
)
;
@
(
negedge
CLK
)
;
end
end
endtask
task
axi_write_single_w
;
// address in dwords
input
[
29
:
0
]
address
;
input
[
31
:
0
]
data
;
begin
`ifdef
DEBUG_WR_SINGLE
$
display
(
"axi_write_single_w %h:%h @ %t"
,
address
,
data
,
$
time
)
;
`endif
axi_write_single
(
{
address
,
2'b0
},
data
)
;
end
endtask
task
axi_write_single
;
// address in bytes, not words
input
[
31
:
0
]
address
;
input
[
31
:
0
]
data
;
begin
axi_write_addr_data
(
GLOBAL_WRITE_ID
,
// id
// address << 2, // addr
address
&
32'hfffffffc
,
// addr
data
,
4'h0
,
// len - single
1
,
// burst type - increment
1'b1
,
// data_en
4'hf
,
// wstrb
1'b1
// last
)
;
GLOBAL_WRITE_ID
<=
GLOBAL_WRITE_ID
+
1
;
#
0.1
;
// without this delay axi_write_addr_data() used old value of GLOBAL_WRITE_ID
end
endtask
task
axi_write_addr_data
;
input
[
11
:
0
]
id
;
input
[
31
:
0
]
addr
;
input
[
31
:
0
]
data
;
input
[
3
:
0
]
len
;
input
[
1
:
0
]
burst
;
input
data_en
;
// if 0 - do not send data, only address
input
[
3
:
0
]
wstrb
;
input
last
;
begin
IRQ_EN
=
0
;
wait
(
CLK
)
;
while
(
!
MAIN_GO
)
begin
wait
(
!
CLK
)
;
wait
(
CLK
)
;
end
axi_write_addr_data_inner
(
id
,
addr
,
data
,
len
,
burst
,
data_en
,
wstrb
,
last
)
;
IRQ_EN
=
1
;
if
(
IRQS
)
begin
@
(
posedge
CLK
)
;
@
(
negedge
CLK
)
;
end
end
endtask
task
axi_write_data
;
input
[
11
:
0
]
id
;
input
[
31
:
0
]
data
;
input
[
3
:
0
]
wstrb
;
input
last
;
begin
IRQ_EN
=
0
;
wait
(
CLK
)
;
while
(
!
MAIN_GO
)
begin
wait
(
!
CLK
)
;
wait
(
CLK
)
;
end
axi_write_data_inner
(
id
,
data
,
wstrb
,
last
)
;
IRQ_EN
=
1
;
if
(
IRQS
)
begin
@
(
posedge
CLK
)
;
@
(
negedge
CLK
)
;
end
end
endtask
// Tasks called from ISR
task
read_contol_register_irq
;
input
[
29
:
0
]
reg_addr
;
output
[
31
:
0
]
rslt
;
begin
read_and_wait_w_irq
(
CONTROL_RBACK_ADDR
+
reg_addr
,
rslt
)
;
end
endtask
task
read_status_irq
;
input
[
STATUS_DEPTH
-
1
:
0
]
address
;
output
[
31
:
0
]
rslt
;
begin
read_and_wait_w_irq
(
STATUS_ADDR
+
address
,
rslt
)
;
end
endtask
task
read_and_wait_w_irq
;
input
[
29
:
0
]
address
;
output
[
31
:
0
]
rslt
;
begin
read_and_wait_irq
(
{
address
,
2'b0
},
rslt
)
;
end
endtask
task
read_and_wait_irq
;
input
[
31
:
0
]
address
;
output
reg
[
31
:
0
]
rslt
;
begin
axi_read_addr_irq
(
GLOBAL_READ_ID
,
// id
address
&
32'hfffffffc
,
// addr
4'h0
,
// len - single
1
// burst type - increment
)
;
GLOBAL_READ_ID
<=
GLOBAL_READ_ID
+
1
;
wait
(
!
CLK
&&
rvalid
&&
rready
)
;
wait
(
CLK
)
;
rslt
<=
rdata
;
wait
(
!
CLK
)
;
// registered_rdata should be valid on exit
end
endtask
task
axi_read_addr_irq
;
// called ferom the main loop, not from interrupts
input
[
11
:
0
]
id
;
input
[
31
:
0
]
addr
;
input
[
3
:
0
]
len
;
input
[
1
:
0
]
burst
;
begin
// IRQ_EN = 0;
// wait (CLK);
// while (!MAIN_GO) begin
// wait (!CLK);
// wait (CLK);
// end
axi_read_addr_inner
(
id
,
addr
,
len
,
burst
)
;
// IRQ_EN = 1;
end
endtask
task
write_contol_register_irq
;
input
[
29
:
0
]
reg_addr
;
// input integer reg_addr;
input
[
31
:
0
]
data
;
begin
axi_write_single_w_irq
(
CONTROL_ADDR
+
reg_addr
,
data
)
;
end
endtask
task
axi_write_single_w_irq
;
// address in dwords
input
[
29
:
0
]
address
;
input
[
31
:
0
]
data
;
begin
`ifdef
DEBUG_WR_SINGLE
$
display
(
"axi_write_single_w %h:%h @ %t"
,
address
,
data
,
$
time
)
;
`endif
axi_write_single_irq
(
{
address
,
2'b0
},
data
)
;
end
endtask
task
axi_write_single_irq
;
// address in bytes, not words
input
[
31
:
0
]
address
;
input
[
31
:
0
]
data
;
begin
axi_write_addr_data_irq
(
GLOBAL_WRITE_ID
,
// id
address
&
32'hfffffffc
,
// addr
data
,
4'h0
,
// len - single
1
,
// burst type - increment
1'b1
,
// data_en
4'hf
,
// wstrb
1'b1
// last
)
;
GLOBAL_WRITE_ID
<=
GLOBAL_WRITE_ID
+
1
;
#
0.1
;
// without this delay axi_write_addr_data() used old value of GLOBAL_WRITE_ID
end
endtask
task
axi_write_addr_data_irq
;
input
[
11
:
0
]
id
;
input
[
31
:
0
]
addr
;
input
[
31
:
0
]
data
;
input
[
3
:
0
]
len
;
input
[
1
:
0
]
burst
;
input
data_en
;
// if 0 - do not send data, only address
input
[
3
:
0
]
wstrb
;
input
last
;
begin
// IRQ_EN = 0;
// wait (CLK);
// while (!MAIN_GO) begin
// wait (!CLK);
// wait (CLK);
// end
axi_write_addr_data_inner
(
id
,
addr
,
data
,
len
,
burst
,
data_en
,
wstrb
,
last
)
;
// IRQ_EN = 1;
end
endtask
// Tasks common for main ind ISR
task
axi_write_addr_data_inner
;
input
[
11
:
0
]
id
;
input
[
31
:
0
]
addr
;
input
[
31
:
0
]
data
;
input
[
3
:
0
]
len
;
input
[
1
:
0
]
burst
;
input
data_en
;
// if 0 - do not send data, only address
input
[
3
:
0
]
wstrb
;
input
last
;
reg
data_sent
;
// wire data_sent_d;
// assign #(.1) data_sent_d= data_sent;
begin
wait
(
!
CLK
&&
dutm0_awready
)
;
dutm0_awid
<=
id
;
dutm0_awaddr
<=
addr
;
dutm0_awlen
<=
len
;
dutm0_awsize
<=
2'b10
;
dutm0_awburst
<=
burst
;
dutm0_awvalid
<=
1'b1
;
if
(
data_en
&&
dutm0_wready
)
begin
dutm0_wid
<=
id
;
dutm0_wdata
<=
data
;
dutm0_wstb
<=
wstrb
;
dutm0_wlast
<=
last
;
dutm0_wvalid
<=
1'b1
;
data_sent
<=
1'b1
;
end
else
begin
data_sent
<=
1'b0
;
end
DEBUG1
<=
1'b1
;
wait
(
CLK
)
;
DEBUG1
<=
1'b0
;
dutm0_awid
<=
'
hz
;
dutm0_awaddr
<=
'
hz
;
dutm0_awlen
<=
'
hz
;
dutm0_awsize
<=
'
hz
;
dutm0_awburst
<=
'
hz
;
dutm0_awvalid
<=
1'b0
;
DEBUG2
<=
1'b1
;
if
(
data_sent
)
begin
dutm0_wid
<=
'
hz
;
dutm0_wdata
<=
'
hz
;
dutm0_wstb
<=
'
hz
;
dutm0_wlast
<=
'
hz
;
dutm0_wvalid
<=
1'b0
;
end
// Now sent data if it was not sent simultaneously with the address
if
(
data_en
&&
!
data_sent
)
begin
DEBUG3
<=
1'b1
;
wait
(
!
CLK
&&
dutm0_wready
)
;
DEBUG3
<=
1'b0
;
dutm0_wid
<=
id
;
dutm0_wdata
<=
data
;
dutm0_wstb
<=
wstrb
;
dutm0_wlast
<=
last
;
dutm0_wvalid
<=
1'b1
;
wait
(
CLK
)
;
DEBUG3
<=
1'bx
;
dutm0_wid
<=
'
hz
;
dutm0_wdata
<=
'
hz
;
dutm0_wstb
<=
'
hz
;
dutm0_wlast
<=
'
hz
;
dutm0_wvalid
<=
1'b0
;
end
DEBUG2
<=
1'b0
;
#
0.1
;
data_sent
<=
1'b0
;
#
0.1
;
end
endtask
task
axi_write_data_inner
;
input
[
11
:
0
]
id
;
input
[
31
:
0
]
data
;
input
[
3
:
0
]
wstrb
;
input
last
;
begin
wait
(
!
CLK
&&
dutm0_wready
)
;
dutm0_wid
<=
id
;
dutm0_wdata
<=
data
;
dutm0_wstb
<=
wstrb
;
dutm0_wlast
<=
last
;
dutm0_wvalid
<=
1'b1
;
wait
(
CLK
)
;
dutm0_wid
<=
12
'
hz
;
dutm0_wdata
<=
'
hz
;
dutm0_wstb
<=
4
'
hz
;
dutm0_wlast
<=
1'bz
;
dutm0_wvalid
<=
1'b0
;
#
0.1
;
end
endtask
task
axi_read_addr_inner
;
// regardless of main loop/interrupts
input
[
11
:
0
]
id
;
input
[
31
:
0
]
addr
;
input
[
3
:
0
]
len
;
input
[
1
:
0
]
burst
;
begin
wait
(
!
CLK
&&
dutm0_arready
)
;
dutm0_arid
<=
id
;
dutm0_araddr
<=
addr
;
dutm0_arlen
<=
len
;
dutm0_arsize
<=
2'b10
;
dutm0_arburst
<=
burst
;
dut_arvalid
<=
1'b1
;
wait
(
CLK
)
;
dutm0_arid
<=
12
'
hz
;
dutm0_araddr
<=
'
hz
;
dutm0_arlen
<=
4
'
hz
;
dutm0_arsize
<=
2
'
hz
;
dutm0_arburst
<=
2
'
hz
;
dut_arvalid
<=
1'b0
;
LAST_ARID
<=
id
;
NUM_WORDS_EXPECTED
<=
NUM_WORDS_EXPECTED
+
len
+
1
;
end
endtask
`endif
// SHOW_TMP_TASKS
endmodule
endmodule
cocotb/x393interfaces.py
View file @
860b1594
...
@@ -17,10 +17,11 @@ from __future__ import print_function
...
@@ -17,10 +17,11 @@ from __future__ import print_function
#
#
# You should have received a copy of the GNU General Public License
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http:#www.gnu.org/licenses/>.
# along with this program. If not, see <http:#www.gnu.org/licenses/>.
@author: Andrey Filippov
@brief I/O Interfaces of the x393 project for simulation using cocotb
@copyright: 2016 Elphel, Inc.
@author Andrey Filippov
@license: GPLv3.0+
@copyright 2016 Elphel, Inc.
@contact: andrey@elphel.coml
@license GPLv3.0+
@contact andrey@elphel.coml
Uses code from https://github.com/potentialventures/cocotb/blob/master/cocotb/drivers/amba.py
Uses code from https://github.com/potentialventures/cocotb/blob/master/cocotb/drivers/amba.py
Below are the copyright/license notices of the amba.py
Below are the copyright/license notices of the amba.py
...
...
py393/x393_mem.py
View file @
860b1594
...
@@ -80,7 +80,7 @@ class X393Mem(object):
...
@@ -80,7 +80,7 @@ class X393Mem(object):
try
:
try
:
X393_CLIENT
.
start
()
X393_CLIENT
.
start
()
except
:
except
:
print
(
"Failed to communicate to the server. Is it started? Swit
hching to dry t
un mode"
)
print
(
"Failed to communicate to the server. Is it started? Swit
ching to dry r
un mode"
)
X393_CLIENT
=
True
X393_CLIENT
=
True
...
@@ -170,7 +170,6 @@ class X393Mem(object):
...
@@ -170,7 +170,6 @@ class X393Mem(object):
@param quiet - reduce output
@param quiet - reduce output
"""
"""
if
X393_CLIENT
is
True
:
if
X393_CLIENT
is
True
:
# if self.DRY_MODE:
print
(
"simulated: write_mem(0x
%
x,0x
%
x)"
%
(
addr
,
data
))
print
(
"simulated: write_mem(0x
%
x,0x
%
x)"
%
(
addr
,
data
))
return
return
elif
not
X393_CLIENT
is
None
:
elif
not
X393_CLIENT
is
None
:
...
@@ -184,23 +183,11 @@ class X393Mem(object):
...
@@ -184,23 +183,11 @@ class X393Mem(object):
page_addr
=
addr
&
(
~
(
self
.
PAGE_SIZE
-
1
))
page_addr
=
addr
&
(
~
(
self
.
PAGE_SIZE
-
1
))
page_offs
=
addr
-
page_addr
page_offs
=
addr
-
page_addr
mm
=
self
.
wrap_mm
(
f
,
page_addr
)
mm
=
self
.
wrap_mm
(
f
,
page_addr
)
# if (page_addr>=0x80000000):
# page_addr-= (1<<32)
# mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr)
packedData
=
struct
.
pack
(
self
.
ENDIAN
+
"L"
,
data
)
packedData
=
struct
.
pack
(
self
.
ENDIAN
+
"L"
,
data
)
d
=
struct
.
unpack
(
self
.
ENDIAN
+
"L"
,
packedData
)[
0
]
d
=
struct
.
unpack
(
self
.
ENDIAN
+
"L"
,
packedData
)[
0
]
mm
[
page_offs
:
page_offs
+
4
]
=
packedData
mm
[
page_offs
:
page_offs
+
4
]
=
packedData
if
quiet
<
2
:
if
quiet
<
2
:
print
(
"0x
%08
x <== 0x
%08
x (
%
d)"
%
(
addr
,
d
,
d
))
print
(
"0x
%08
x <== 0x
%08
x (
%
d)"
%
(
addr
,
d
,
d
))
'''
if MONITOR_EMIO and VEBOSE:
gpio0=read_mem (0xe000a068)
gpio1=read_mem (0xe000a06c)
print("GPIO:
%04
x
%04
x
%04
x
%04
x"
%
(gpio1>>16, gpio1 & 0xffff, gpio0>>16, gpio0 & 0xffff))
if ((gpio0 & 0xc) != 0xc) or ((gpio0 & 0xff00) != 0):
print("******** AXI STUCK ************")
exit (0)
'''
def
read_mem
(
self
,
addr
,
quiet
=
1
):
def
read_mem
(
self
,
addr
,
quiet
=
1
):
'''
'''
...
...
x393_1_8_2.Doxyfile
View file @
860b1594
...
@@ -104,7 +104,7 @@ WARN_LOGFILE = log.txt
...
@@ -104,7 +104,7 @@ WARN_LOGFILE = log.txt
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
# Configuration options related to the input files
# Configuration options related to the input files
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
INPUT = . axi compressor_jp dsp includes logger memctrl sensor simulation_modules timing util_modules wrap x393_sata
py393
helpers
INPUT = . axi compressor_jp dsp includes logger memctrl sensor simulation_modules timing util_modules wrap x393_sata helpers
INPUT_ENCODING = UTF-8
INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.v *.vh *.ucf *.qsf *.tcl *.py
FILE_PATTERNS = *.v *.vh *.ucf *.qsf *.tcl *.py
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment