in reply to Reading block

Assuming you missed my comments in the Chatterbox yesterday (or maybe you chose to ignore them:), I will re-state them here. Since Verilog employs a comlpex syntax, a complex parser is required. Obviously, if you can control the format of the Verilog source code you are trying to parse, you may be able to roll your own simple parser. Since that is unlikely, I whole-heartedly agree with shoness' advice on trying to use the CPAN modules.

Here are some of the common pitfalls you are facing (and there are many, many more):

Here are some techniques I have used to overcome some of these issues. You could pre-process the Verilog file to remove all comments using the regex in perlfaq6:

How do I use a regular expression to strip C style comments from a file?

This will work in most (but not all) cases.

If you have access to the Cadence ncverilog simulation tools, you could first compile the Verilog files, then de-compile the files using ncdc. This tool allows for some control over the resulting de-compiled files so that parsing may be simpler. I am not sure if other simulation tools have the same capability.

If you can edit the Verilog source files, you could embed pragmas in comments such as // always_end -- but that will only help you for future development.

That being said, here is some EXTREMELY BRITTLE code which works for the Verilog code you provided:

use strict; use warnings; my @ins; my @outs; my @blocks; my $flag = 0; while (<DATA>) { if (/\binput\b/) { push @ins , $_ } if (/\boutput\b/) { push @outs, $_ } if (/\balways\b/) { s/^.*\b(always)\b/$1/; push @blocks, $_; $flag = 1; next; } if ($flag) { push @blocks, $_; $flag = 0 if (/^\s*$/); # blank line ends always block } } create_file('inputs.v' , @ins); create_file('outputs.v', @outs); create_file('always.v' , @blocks); sub create_file { my $file = shift; open my $fileHandle, '>', $file or die "Unable to create $file: $! +\n"; print $fileHandle $_ for (@_); close $fileHandle or die "Unable to close file $file: $!\n"; } __DATA__ input [31:0] ucast_mem_wdata; input [31:0] ucast_mem_wren; input ucast_mem_wr; input ucast_mem_rd; output [31:0] ucast_mem_rdata; wire [BMU_MEM_ADDR_BITS-1:0] mem_addr; always @ (posedge sys_clk +or negedge sys_reset_n) begin if (!sys_reset_n) ucast_int_mem_rd_r <= 0; else ucast_int_mem_rd_r <= ucast_int_mem_rd & !ucast_access; end endmodule

Here is the output:

> ./701343.pl > cat inputs.v input [31:0] ucast_mem_wdata; input [31:0] ucast_mem_wren; input ucast_mem_wr; input ucast_mem_rd; > cat outputs.v output [31:0] ucast_mem_rdata; > cat always.v always @ (posedge sys_clk or negedge sys_reset_n) begin if (!sys_reset_n) ucast_int_mem_rd_r <= 0; else ucast_int_mem_rd_r <= ucast_int_mem_rd & !ucast_access; end >