Skip to content

Commit

Permalink
check systemverilog keyword (#108, rggen/rggen#154)
Browse files Browse the repository at this point in the history
  • Loading branch information
taichi-ishitani authored Jan 12, 2025
1 parent d4a8e6d commit 5934bc6
Show file tree
Hide file tree
Showing 5 changed files with 197 additions and 0 deletions.
5 changes: 5 additions & 0 deletions lib/rggen/systemverilog/ral.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require_relative 'common'
require_relative 'register_map/keyword_checker'
require_relative 'ral/feature'
require_relative 'ral/register_common'

Expand Down Expand Up @@ -30,4 +31,8 @@
'ral/bit_field/type/rwc_rwhw_rws',
'ral/bit_field/type/rwe_rwl'
]

plugin.files [
'register_map/name'
]
end
62 changes: 62 additions & 0 deletions lib/rggen/systemverilog/register_map/keyword_checker.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# frozen_string_literal: true

module RgGen
module SystemVerilog
module RegisterMap
module KeywordChecker
SYSTEMVERILOG_KEYWORDS = [
'accept_on', 'alias', 'always', 'always_comb', 'always_ff', 'always_latch',
'and', 'assert', 'assign', 'assume', 'automatic', 'before', 'begin', 'bind',
'bins', 'binsof', 'bit', 'break', 'buf', 'bufif0', 'bufif1', 'byte', 'case',
'casex', 'casez', 'cell', 'chandle', 'checker', 'class', 'clocking', 'cmos',
'config', 'const', 'constraint', 'context', 'continue', 'cover', 'covergroup',
'coverpoint', 'cross', 'deassign', 'default', 'defparam', 'design', 'disable',
'dist', 'do', 'edge', 'else', 'end', 'endcase', 'endchecker', 'endclass',
'endclocking', 'endconfig', 'endfunction', 'endgenerate', 'endgroup',
'endinterface', 'endmodule', 'endpackage', 'endprimitive', 'endprogram',
'endproperty', 'endspecify', 'endsequence', 'endtable', 'endtask', 'enum',
'event', 'eventually', 'expect', 'export', 'extends', 'extern', 'final',
'first_match', 'for', 'force', 'foreach', 'forever', 'fork', 'forkjoin',
'function', 'generate', 'genvar', 'global', 'highz0', 'highz1', 'if', 'iff',
'ifnone', 'ignore_bins', 'illegal_bins', 'implements', 'implies', 'import',
'incdir', 'include', 'initial', 'inout', 'input', 'inside', 'instance', 'int',
'integer', 'interconnect', 'interface', 'intersect', 'join', 'join_any',
'join_none', 'large', 'let', 'liblist', 'library', 'local', 'localparam',
'logic', 'longint', 'macromodule', 'matches', 'medium', 'modport', 'module',
'nand', 'negedge', 'nettype', 'new', 'nexttime', 'nmos', 'nor',
'noshowcancelled', 'not', 'notif0', 'notif1', 'null', 'or', 'output', 'package',
'packed', 'parameter', 'pmos', 'posedge', 'primitive', 'priority', 'program',
'property', 'protected', 'pull0', 'pull1', 'pulldown', 'pullup',
'pulsestyle_ondetect', 'pulsestyle_onevent', 'pure', 'rand', 'randc',
'randcase', 'randsequence', 'rcmos', 'real', 'realtime', 'ref', 'reg',
'reject_on', 'release', 'repeat', 'restrict', 'return', 'rnmos', 'rpmos',
'rtran', 'rtranif0', 'rtranif1', 's_always', 's_eventually', 's_nexttime',
's_until', 's_until_with', 'scalared', 'sequence', 'shortint', 'shortreal',
'showcancelled', 'signed', 'small', 'soft', 'solve', 'specify', 'specparam',
'static', 'string', 'strong', 'strong0', 'strong1', 'struct', 'super',
'supply0', 'supply1', 'sync_accept_on', 'sync_reject_on', 'table', 'tagged',
'task', 'this', 'throughout', 'time', 'timeprecision', 'timeunit', 'tran',
'tranif0', 'tranif1', 'tri', 'tri0', 'tri1', 'triand', 'trior', 'trireg',
'type', 'typedef', 'union', 'unique', 'unique0', 'unsigned', 'until',
'until_with', 'untyped', 'use', 'uwire', 'var', 'vectored', 'virtual',
'void', 'wait', 'wait_order', 'wand', 'weak', 'weak0', 'weak1', 'while',
'wildcard', 'wire', 'with', 'within', 'wor', 'xnor', 'xor'
].freeze

def self.included(klass)
klass.class_eval do
verify(:feature) do
error_condition do
@name && SYSTEMVERILOG_KEYWORDS.include?(@name)
end
message do
layer_name = component.layer.to_s.sub('_', ' ')
"systemverilog keyword is not allowed for #{layer_name} name: #{@name}"
end
end
end
end
end
end
end
end
9 changes: 9 additions & 0 deletions lib/rggen/systemverilog/register_map/name.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

[:register_block, :register_file, :register, :bit_field].each do |layer|
RgGen.modify_simple_feature(layer, :name) do
register_map do
include RgGen::SystemVerilog::RegisterMap::KeywordChecker
end
end
end
5 changes: 5 additions & 0 deletions lib/rggen/systemverilog/rtl.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require_relative 'common'
require_relative 'register_map/keyword_checker'
require_relative 'rtl/feature'
require_relative 'rtl/partial_sum'
require_relative 'rtl/register_index'
Expand Down Expand Up @@ -66,4 +67,8 @@
'rtl_package/register/sv_rtl_package',
'rtl_package/register_block/sv_rtl_package'
]

plugin.files [
'register_map/name'
]
end
116 changes: 116 additions & 0 deletions spec/rggen/systemverilog/register_map/name_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# frozen_string_literal: true

RSpec.describe 'regiter_map/name' do
include_context 'clean-up builder'
include_context 'register map common'

before(:all) do
RgGen.enable(:register_block, :name)
RgGen.enable(:register_file, :name)
RgGen.enable(:register, :name)
RgGen.enable(:bit_field, :name)
end

let(:systemverilog_keywords) do
[
'accept_on', 'alias', 'always', 'always_comb', 'always_ff',
'always_latch', 'and', 'assert', 'assign', 'assume', 'automatic',
'before', 'begin', 'bind', 'bins', 'binsof', 'bit', 'break', 'buf',
'bufif0', 'bufif1', 'byte', 'case', 'casex', 'casez', 'cell', 'chandle',
'checker', 'class', 'clocking', 'cmos', 'config', 'const', 'constraint',
'context', 'continue', 'cover', 'covergroup', 'coverpoint', 'cross',
'deassign', 'default', 'defparam', 'design', 'disable', 'dist', 'do',
'edge', 'else', 'end', 'endcase', 'endchecker', 'endclass', 'endclocking',
'endconfig', 'endfunction', 'endgenerate', 'endgroup', 'endinterface',
'endmodule', 'endpackage', 'endprimitive', 'endprogram', 'endproperty',
'endspecify', 'endsequence', 'endtable', 'endtask', 'enum', 'event',
'eventually', 'expect', 'export', 'extends', 'extern', 'final', 'first_match',
'for', 'force', 'foreach', 'forever', 'fork', 'forkjoin', 'function',
'generate', 'genvar', 'global', 'highz0', 'highz1', 'if', 'iff', 'ifnone',
'ignore_bins', 'illegal_bins', 'implements', 'implies', 'import', 'incdir',
'include', 'initial', 'inout', 'input', 'inside', 'instance', 'int',
'integer', 'interconnect', 'interface', 'intersect', 'join', 'join_any',
'join_none', 'large', 'let', 'liblist', 'library', 'local', 'localparam',
'logic', 'longint', 'macromodule', 'matches', 'medium', 'modport',
'module', 'nand', 'negedge', 'nettype', 'new', 'nexttime', 'nmos',
'nor', 'noshowcancelled', 'not', 'notif0', 'notif1', 'null', 'or',
'output', 'package', 'packed', 'parameter', 'pmos', 'posedge', 'primitive',
'priority', 'program', 'property', 'protected', 'pull0', 'pull1',
'pulldown', 'pullup', 'pulsestyle_ondetect', 'pulsestyle_onevent',
'pure', 'rand', 'randc', 'randcase', 'randsequence', 'rcmos', 'real',
'realtime', 'ref', 'reg', 'reject_on', 'release', 'repeat', 'restrict',
'return', 'rnmos', 'rpmos', 'rtran', 'rtranif0', 'rtranif1', 's_always',
's_eventually', 's_nexttime', 's_until', 's_until_with', 'scalared',
'sequence', 'shortint', 'shortreal', 'showcancelled', 'signed', 'small',
'soft', 'solve', 'specify', 'specparam', 'static', 'string', 'strong',
'strong0', 'strong1', 'struct', 'super', 'supply0', 'supply1',
'sync_accept_on', 'sync_reject_on', 'table', 'tagged', 'task', 'this',
'throughout', 'time', 'timeprecision', 'timeunit', 'tran', 'tranif0',
'tranif1', 'tri', 'tri0', 'tri1', 'triand', 'trior', 'trireg', 'type',
'typedef', 'union', 'unique', 'unique0', 'unsigned', 'until', 'until_with',
'untyped', 'use', 'uwire', 'var', 'vectored', 'virtual', 'void', 'wait',
'wait_order', 'wand', 'weak', 'weak0', 'weak1', 'while', 'wildcard',
'wire', 'with', 'within', 'wor', 'xnor', 'xor'
]
end

context 'レジスタブロック名がSystemVerilogの予約語に一致する場合' do
it 'RegiterMapErrorを起こす' do
systemverilog_keywords.each do |keyword|
expect {
create_register_map do
register_block { name keyword }
end
}.to raise_register_map_error "systemverilog keyword is not allowed for register block name: #{keyword}"
end
end
end

context 'レジスタファイル名がSystemVerilogの予約語に一致する場合' do
it 'RegiterMapErrorを起こす' do
systemverilog_keywords.each do |keyword|
expect {
create_register_map do
register_block do
name 'block_0'
register_file { name keyword }
end
end
}.to raise_register_map_error "systemverilog keyword is not allowed for register file name: #{keyword}"
end
end
end

context 'レジスタ名がSystemVerilogの予約語に一致する場合' do
it 'RegiterMapErrorを起こす' do
systemverilog_keywords.each do |keyword|
expect {
create_register_map do
register_block do
name 'block_0'
register { name keyword }
end
end
}.to raise_register_map_error "systemverilog keyword is not allowed for register name: #{keyword}"
end
end
end

context 'ビットフィールド名がSystemVerilogの予約語に一致する場合' do
it 'RegiterMapErrorを起こす' do
systemverilog_keywords.each do |keyword|
expect {
create_register_map do
register_block do
name 'block_0'
register do
name 'register_0'
bit_field { name keyword }
end
end
end
}.to raise_register_map_error "systemverilog keyword is not allowed for bit field name: #{keyword}"
end
end
end
end

0 comments on commit 5934bc6

Please sign in to comment.