1

下午好,

我正在尝试编写一个给定输入文件的 tcl 脚本

input               hreadyin;
input  wire         htrans;       
input  wire [7:0]   haddr;   
output logic [31:0] hrdata;
output              hreadyout;

会产生

hreadyin(hreadyin),
htrans(htrans),
haddr(haddr[7:0]),
hrdata(hrdata[31:0]),
hready(hreadyout)

换句话说,格式是:

<input/output> <wire/logic optional> <width, optional> <paramName>;

每个空格之间的空格数不受限制。

我从输入文件中读取没有问题,并且能够将每一行放入一个$line元素中。现在我一直在尝试这样的事情:

  set param0 [split $line "input"]
  set param1 [lindex $param0 1]

但由于并非所有行都包含 "input"行,因此我无法获得我想要的元素(名称和宽度,如果存在)。

tcl 中是否有另一个命令能够进行这种解析?

4

3 回答 3

2

regexp 命令对于查找由任意空格分隔的单词很有用:

while {[gets $fh line] != -1} {
    # get all whitespace-separated words in the line, ignoring the semi-colon
    set i [string first ";" $line]
    set fields [regexp -inline -all {\S+} [string range $line 0 $i-1]]

    switch -exact -- [llength $fields] {
        2 - 3 {
            set name [lindex $fields end]
            puts [format "%s(%s)," $name $name]
        }
        4 {
            lassign $fields - - width name
            puts [format "%s(%s%s)," $name $name $width]
        }
    }
}
于 2013-06-04T18:00:40.397 回答
2

我认为你应该看看类似的东西

# Compress all multiple spaces to single spaces

set compressedLine [resgub " +" $line " "]

set items [split [string range $compressedLine 0 end-1] $compressedLine " "]
switch [llength $items] {
    2 {
        # Handle case where neither wire/logic nor width is specificed

        set inputOutput [lindex $items 0]
        set paramName [lindex $items 1]
        .
        .
        .
    }

    4 {
        # Handle case where both wire/logic and width are specified

        set inputOutput [lindex $items 0]
        set wireLogic [lindex $items 1]
        set width [lindex $items 2]
        set paramName [lindex $items 3]
        .
        .
        .
    }

    default {
        # Don't know how to handle other cases - add them in if you know
        puts stderr "Can't handle $line
    }
}

我希望完全指定电线/逻辑和宽度之一是不合法的-您需要努力确定哪个是哪个。

(注意[string range...]小提琴在行尾丢弃分号)

于 2013-06-04T17:11:50.957 回答
1

或者,如果您可以编写一个捕获正确数据的正则表达式,您可以这样做:

set data [open "file.txt" r]
set output [open "output.txt" w]

while {[gets $data line] != -1} {
    regexp -- {(\[\d+:\d+\])?\s*(\w+);} $line - width params
    puts $output "$params\($params$width\),"
}

close $data
close $output

这还将打印您在预期输出中插入的逗号,但也会将其插入最后一行,以便您获得:

hreadyin(hreadyin),
htrans(htrans),
haddr(haddr[7:0]),
hrdata(hrdata[31:0]),
hready(hreadyout),

如果你不想要它并且文件不是太大(显然列表的限制是 2147483672 字节,我将使用它),你可以使用这样的组:

set data [open "file.txt" r]
set output [open "output.txt" w]

set listing "" #Empty list

while {[gets $data line] != -1} {
    regexp -- {(\[\d+:\d+\])?\s*(\w+);} $line - width params
    lappend listing "$params\($params$width\)" #Appending to list instead
}

puts $output [join $listing ",\n"] #Join all in a single go

close $data
close $output
于 2013-06-04T20:43:53.710 回答