rggen 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2396e3bda75fed6482252aa77cb4b4173876357d
4
- data.tar.gz: d8eaa7e4be192d6e904e3ba59a279213adf46b27
3
+ metadata.gz: b4a6ce8cdb613957faf3d1261a338b84a8b631ac
4
+ data.tar.gz: 5cca3d0af73d1aa9d81d6eac43dc583fabb86491
5
5
  SHA512:
6
- metadata.gz: 54fb50cd74efae359260ff966c274ab31777e30ff212084f731ea77928df348faa9d97e92e4e735f4c9e04db1d9115baaa6189e7240f5a92f2ae61126957e529
7
- data.tar.gz: c5cf3cf847bedc4bdf68a2fb372b641d0b4a0735e002e5cf6654eb2c1bf4b3a3d16e269d78228fe497e86a519d7b6089c8e1f598dc5ac765ecd1f8950383c8e7
6
+ metadata.gz: 5f74630a5687e2ab0f8a20ddb647726ee139dc240642c834e1826272bbb29e8b8066b5140c70b33d0cfc45a6828058aac53c51b195d8fb4af34f3078af7a6965
7
+ data.tar.gz: 1de526c92b6c4c6304bdb4d6dcb85d0487fe8c522ad25ac369178ce5901d72f13881e5285cfb443246a8353fa63e8e1eec8b0c49c9bb056cab0f55bcaa9063fb
data/README.md CHANGED
@@ -1,135 +1,43 @@
1
- [![Gem Version](https://badge.fury.io/rb/rggen.svg)](https://badge.fury.io/rb/rggen)
2
- [![Build Status](https://travis-ci.org/taichi-ishitani/rggen.svg?branch=master)](https://travis-ci.org/taichi-ishitani/rggen)
3
- [![Code Climate](https://codeclimate.com/github/taichi-ishitani/rggen/badges/gpa.svg)](https://codeclimate.com/github/taichi-ishitani/rggen)
1
+ [![Gem Version](https://badge.fury.io/rb/rggen.svg)](https://badge.fury.io/rb/rggen)
2
+ [![Build Status](https://travis-ci.org/taichi-ishitani/rggen.svg?branch=master)](https://travis-ci.org/taichi-ishitani/rggen)
3
+ [![Code Climate](https://codeclimate.com/github/taichi-ishitani/rggen/badges/gpa.svg)](https://codeclimate.com/github/taichi-ishitani/rggen)
4
4
  [![Test Coverage](https://codeclimate.com/github/taichi-ishitani/rggen/badges/coverage.svg)](https://codeclimate.com/github/taichi-ishitani/rggen/coverage)
5
5
  [![Join the chat at https://gitter.im/taichi-ishitani/rggen](https://badges.gitter.im/taichi-ishitani/rggen.svg)](https://gitter.im/taichi-ishitani/rggen?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
6
-
7
- # RgGen
8
-
9
- RgGen is a code generation tool for SoC designers.
10
- It will automatically generate source code for control registers in a SoC design, e.g. RTL, UVM RAL model, from its register map document.
11
- Also RgGen is customizable so you can build your specific generate tool.
12
-
13
- ## Ruby
14
-
15
- RgGen is written in the [*Ruby*](https://www.ruby-lang.org/en/about/) programing language and supports version 2.0 or later.
16
- If you don't have above version of Ruby, you need to install the Ruby at first.
17
- To install the Ruby, see [this page](https://www.ruby-lang.org/en/downloads/).
18
-
19
- ## Installation
20
-
21
- To install RgGen and required libraries, use the following command:
22
-
23
- $ gem install rggen
24
-
25
- RgGen will be installed under your system root.
26
-
27
- If you want to install them on other location, you need to specify the install directory and set the **GEM_PATH** environment variable like below:
28
-
29
- $ gem install --install-dir YOUR_INSTALL_DIRECTORY rggen
30
- $ export GEM_PATH=YOUR_INSTALL_DIRECTORY
31
-
32
- ## Usage
33
-
34
- ### Writing Configuration File
35
-
36
- A configuration file is to describe attributes of your design, e.g. data bus width, address bus width, host interface protocol.
37
- RgGen supports YAML and JSON for its file format and allows to use Hash notation to describe attributes of your design like below.
38
-
39
- - YAML
40
- ~~~YAML
41
- address_width: 16
42
- data_width: 32
43
- host_if: apb
44
- ~~~
45
- - JSON
46
- ~~~JSON
47
- {
48
- "address_width": 16,
49
- "data_width": 32,
50
- "host_if": "apb"
51
- }
52
- ~~~
53
-
54
- These attributes have default values. If you use a default value, you don't specify its value.
55
- In addition, if you use default values for all of attributes, you don't need to write a configuration file.
56
-
57
- ### Writing Register Map Document
58
-
59
- RgGen allows to use a spreadsheet to input the register map of your design so you can directly input your register map document to RgGen.
60
- To do this, you need to write your register map document according to below table format.
61
-
62
- | |A |B |C |D |E |F |G |H |I |J |K |
63
- |:---|:---|:-------------|:------------|:--------------|:--------------------------------|:-------|:-------------|:---------|:---|:-----------|:--------|
64
- |1 | |Block Name |block_0 | | | | | | | | |
65
- |2 | |Byte Size |256 | | | | | | | | |
66
- |3 | | | | | | | | | | | |
67
- |4 | |Offset Address|Register Name|Array Dimension|Shadow Index |External|Bit Assignment|Field Name|Type|Iitial Value|Reference|
68
- |5 | |0x00 |register_0 | | | |[31:16] |field_0_0 |rw |0 | |
69
- |6 | | | | | | |[15:0] |field_0_1 |rw |0 | |
70
- |7 | |0x04 |register_1 | | | |[16] |field_1_0 |rw |0 | |
71
- |8 | | | | | | |[0] |field_1_1 |ro | | |
72
- |9 | |0x10 - 0x1F |register_2 |[4] | | |[7:0] |field_2_0 |rw |0 | |
73
- |10 | |0x20 - 0x3F |register_3 | | |true | | | | | |
74
- |11 | |0x40 |register_4 |[2, 4] |field_1_0:1, field_0_0, field_0_1| |[7:0] |field_4_0 |rw |0 | |
75
- |12 | |0x44 |register_5 | | | |[8] |field_5_0 |w0s |0 | |
76
- |13 | | | | | | |[0] |field_5_1 |w1s |0 | |
77
- |14 | |0x48 |register_6 | | | |[8] |field_6_0 |w0c |0 |field_1_0|
78
- |15 | | | | | | |[0] |field_6_1 |w1c |0 |field_1_0|
79
-
80
- By default, RgGen supports CSV, ODS, XLS and XLSX sparedsheet file types.
81
-
82
- ### Generating Source Code
83
-
84
- To generate soruce code from your register map document, use the following command:
85
-
86
- $ rggen your_register_map.xls
87
-
88
- If you have a configuration file, you need to use `-c/--configuration` option:
89
-
90
- $ rggen -c your_configuration.yml your_register_map.xls
91
-
92
- By default, RgGen will generate RTL SV code under `rtl` directory and UVM RAL model under `ral` dicrectory.
93
- In addition, file name of generated files is accoding to below rule.
94
- - RTL
95
- - `your_block_name`.sv
96
- - RAL model
97
- - `your_block_name`_ral_pkg.sv
98
-
99
- ### Compiling Your Design
100
-
101
- RgGen has base RTL modules and RAL model package (the base library) to build generated RTL and UVM RAL models.
102
- Therefore, to compile your design with the base library, you need followins steps:
103
-
104
- 1. Set the RGGEN_HOME environment variable
105
- 2. Link the base library with you design
106
-
107
- **RGGEN_HOME** environement variable is to show the install direcoty.
108
- To set the variable, you can use `--show-home` option like below:
109
-
110
- $ export RGGEN_HOME=`rggen --show-home`
111
-
112
- To link the base library with your design, RgGen has file lists for the base library.
113
- By using the lists, you can compile your design and the base library like below:
114
-
115
- $ simulator \
116
- -f $RGGEN_HOME/rtl/compile.f \
117
- -f $RGGEN_HOME/ral/compile.f \
118
- rtl/your_register_block.sv \
119
- ral/your_register_block_ral_pkg.sv \
120
- your_test_bench.sv \
121
- your_design.v
122
-
123
- ### Note
124
-
125
- Contents of configuration file and register map document and structure of genrerated RTL and RAL model described above are default.
126
- Also you can change these by customizing RgGen.
127
-
128
- ## Development
129
-
130
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
131
-
132
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
6
+
7
+ # RgGen
8
+
9
+ RgGen is a code generation tool for SoC designers.
10
+ It will automatically generate source code for control registers in a SoC design, e.g. RTL, UVM RAL model, from its register map document.
11
+ Also RgGen is customizable so you can build your specific generate tool.
12
+
13
+ ## Ruby
14
+
15
+ RgGen is written in the [*Ruby*](https://www.ruby-lang.org/en/about/) programing language and supports version 2.0 or later.
16
+ If you don't have above version of Ruby, you need to install the Ruby at first.
17
+ To install the Ruby, see [this page](https://www.ruby-lang.org/en/downloads/).
18
+
19
+ ## Installation
20
+
21
+ To install RgGen and required libraries, use the following command:
22
+
23
+ $ gem install rggen
24
+
25
+ RgGen will be installed under your system root.
26
+
27
+ If you want to install them on other location, you need to specify the install directory and set the **GEM_PATH** environment variable like below:
28
+
29
+ $ gem install --install-dir YOUR_INSTALL_DIRECTORY rggen
30
+ $ export GEM_PATH=YOUR_INSTALL_DIRECTORY
31
+
32
+ ## Usage
33
+
34
+ See [this page](https://github.com/taichi-ishitani/rggen/wiki/Getting-Started)
35
+
36
+ ## Development
37
+
38
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
39
+
40
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
133
41
 
134
42
  ## Contact
135
43
 
@@ -139,11 +47,11 @@ If you have any questions, problems, ideas or somethings, you can post them on t
139
47
  2. [Chat room](https://gitter.im/taichi-ishitani/rggen)
140
48
  3. [Mail](mailto:taichi730@gmail.com)
141
49
 
142
- ## Contributing
143
-
144
- Bug reports and pull requests are welcome on GitHub at https://github.com/taichi-ishitani/rggen. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
145
-
146
- ## License
147
-
50
+ ## Contributing
51
+
52
+ Bug reports and pull requests are welcome on GitHub at https://github.com/taichi-ishitani/rggen. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
53
+
54
+ ## License
55
+
148
56
  Copyright © 2015-2016 Taichi Ishitani.
149
57
  RgGen is available as open source under the terms of [the MIT License](LICENSE.txt).
data/lib/rggen.rb CHANGED
@@ -17,6 +17,7 @@ module RgGen
17
17
 
18
18
  require_relative 'rggen/base/hierarchical_accessors'
19
19
  require_relative 'rggen/base/hierarchical_item_accessors'
20
+ require_relative 'rggen/base/internal_struct'
20
21
  require_relative 'rggen/base/component'
21
22
  require_relative 'rggen/base/item'
22
23
  require_relative 'rggen/base/component_factory'
@@ -0,0 +1,28 @@
1
+ module RgGen
2
+ module Base
3
+ module InternalStruct
4
+ private
5
+
6
+ def internal_structs
7
+ @internal_structs ||= {}
8
+ end
9
+
10
+ def define_struct(struct_name, members, &body)
11
+ return if internal_structs.key?(struct_name)
12
+ internal_structs[struct_name] = Struct.new(*members, &body)
13
+ define_method(struct_name) do
14
+ self.class.send(:internal_structs)[struct_name]
15
+ end
16
+ private(struct_name)
17
+ end
18
+
19
+ def inherited(subclass)
20
+ super(subclass)
21
+ return unless instance_variable_defined?(:@internal_structs)
22
+ subclass.instance_variable_set(
23
+ :@internal_structs, Hash[@internal_structs]
24
+ )
25
+ end
26
+ end
27
+ end
28
+ end
@@ -2,6 +2,7 @@ module RgGen
2
2
  module Base
3
3
  class Item
4
4
  extend Forwardable
5
+ extend InternalStruct
5
6
 
6
7
  class << self
7
8
  def define_helpers(&body)
@@ -14,6 +14,7 @@ require_relative 'builtins/bit_field/name'
14
14
  require_relative 'builtins/bit_field/reference'
15
15
  require_relative 'builtins/bit_field/type'
16
16
  require_relative 'builtins/bit_field/rw'
17
+ require_relative 'builtins/bit_field/rwl_rwe'
17
18
  require_relative 'builtins/bit_field/ro'
18
19
  require_relative 'builtins/bit_field/w0c_w1c'
19
20
  require_relative 'builtins/bit_field/w0s_w1s'
@@ -2,11 +2,11 @@ simple_item :bit_field, :field_model do
2
2
  ral do
3
3
  export :model_creation
4
4
 
5
- delegate [:name, :width, :lsb, :access] => :bit_field
5
+ delegate [:name, :width, :lsb, :access, :model_name] => :bit_field
6
6
 
7
7
  build do
8
8
  variable :reg_model, :field_model,
9
- data_type: :rggen_ral_field,
9
+ data_type: model_name,
10
10
  name: name,
11
11
  random: true
12
12
  end
@@ -0,0 +1,15 @@
1
+ rggen_bit_field_rwl_rwe #(
2
+ .LOCK_MODE (<%= lock_mode %>),
3
+ .WIDTH (<%= width %>),
4
+ .INITIAL_VALUE (<%= initial_value %>)
5
+ ) u_<%= bit_field.name %> (
6
+ .clk (<%= register_block.clock %>),
7
+ .rst_n (<%= register_block.reset %>),
8
+ .i_lock_or_enable (<%= lock_or_enable %>),
9
+ .i_command_valid (<%= register_block.host_if.command_valid %>),
10
+ .i_select (<%= register_block.register_select[index] %>),
11
+ .i_write (<%= register_block.host_if.write %>),
12
+ .i_write_data (<%= register_block.host_if.write_data[bit_field.msb, bit_field.lsb] %>),
13
+ .i_write_mask (<%= register_block.host_if.write_mask[bit_field.msb, bit_field.lsb] %>),
14
+ .o_value (<%= value[loop_variables] %>)
15
+ );
@@ -0,0 +1,55 @@
1
+ list_item :bit_field, :type, [:rwl, :rwe] do
2
+ register_map do
3
+ read_write
4
+ need_initial_value
5
+ use_reference width: 1, required: true
6
+ end
7
+
8
+ rtl do
9
+ build do
10
+ output :value_out,
11
+ name: "o_#{bit_field.name}",
12
+ width: width,
13
+ dimensions: dimensions
14
+ end
15
+
16
+ generate_code :module_item do |code|
17
+ code << assign(value_out[loop_variables], value[loop_variables]) << nl
18
+ code << process_template
19
+ end
20
+
21
+ def lock_mode
22
+ { rwl: 1, rwe: 0 }[bit_field.type]
23
+ end
24
+
25
+ def initial_value
26
+ hex(bit_field.initial_value, width)
27
+ end
28
+
29
+ def lock_or_enable
30
+ mode_field.value
31
+ end
32
+
33
+ def mode_field
34
+ register_block.bit_fields.find do |f|
35
+ f.name == bit_field.reference.name
36
+ end
37
+ end
38
+ end
39
+
40
+ ral do
41
+ model_name { "#{class_name}#(#{mode_register}, #{mode_field})" }
42
+
43
+ def class_name
44
+ "rggen_ral_field_#{bit_field.type}"
45
+ end
46
+
47
+ def mode_register
48
+ string(bit_field.reference.register.name)
49
+ end
50
+
51
+ def mode_field
52
+ string(bit_field.reference.name)
53
+ end
54
+ end
55
+ end
@@ -193,11 +193,16 @@ list_item :bit_field, :type do
193
193
  ral do
194
194
  item_base do
195
195
  export :access
196
+ export :model_name
196
197
  export :hdl_path
197
198
 
198
199
  define_helpers do
199
200
  attr_setter :access
200
201
 
202
+ def model_name(&body)
203
+ define_method(:model_name, &body)
204
+ end
205
+
201
206
  def hdl_path(&body)
202
207
  define_method(:hdl_path, &body)
203
208
  end
@@ -207,6 +212,10 @@ list_item :bit_field, :type do
207
212
  string((self.class.access || bit_field.type).to_s.upcase)
208
213
  end
209
214
 
215
+ def model_name
216
+ :rggen_ral_field
217
+ end
218
+
210
219
  def hdl_path
211
220
  "u_#{bit_field.name}.value"
212
221
  end
@@ -1,13 +1,23 @@
1
1
  simple_item :register, :read_data do
2
2
  rtl do
3
- available? do
4
- !register.external?
5
- end
3
+ available? { register.internal? }
6
4
 
7
5
  generate_code :module_item do |buffer|
8
6
  buffer << assign(register_read_data, read_data) << nl
9
7
  end
10
8
 
9
+ define_struct :read_data_entry, [:lsb, :msb, :value, :dummy] do
10
+ def initialize(args)
11
+ self.lsb = args[:lsb]
12
+ self.msb = args[:msb]
13
+ self.value = args[:value]
14
+ self.dummy = args[:dummy] || false
15
+ end
16
+ end
17
+
18
+ delegate [:data_width] => :configuration
19
+ delegate [:loop_variables] => :register
20
+
11
21
  def register_read_data
12
22
  register_block.register_read_data[register.index]
13
23
  end
@@ -21,16 +31,27 @@ simple_item :register, :read_data do
21
31
  end
22
32
 
23
33
  def read_data_expressions
24
- last_lsb = configuration.data_width
25
- expressions = []
26
- readable_fields.each do |field|
27
- padding_bits = last_lsb - field.msb - 1
28
- last_lsb = field.lsb
34
+ read_data_entries.each_cons(2).with_object([]) do |entries, expressions|
35
+ padding_bits = entries[0].lsb - entries[1].msb - 1
29
36
  expressions << hex(0, padding_bits) if padding_bits > 0
30
- expressions << field.value[register.loop_variables]
37
+ expressions << entries[1].value unless entries[1].dummy
38
+ end
39
+ end
40
+
41
+ def read_data_entries
42
+ [].tap do |entries|
43
+ entries << read_data_entry.new(lsb: data_width, dummy: true)
44
+ entries.concat(readable_field_entries)
45
+ entries << read_data_entry.new(msb: -1, dummy: true)
46
+ end
47
+ end
48
+
49
+ def readable_field_entries
50
+ readable_fields.map do |field|
51
+ read_data_entry.new(
52
+ lsb: field.lsb, msb: field.msb, value: field.value[loop_variables]
53
+ )
31
54
  end
32
- expressions << hex(0, last_lsb) if last_lsb > 0
33
- expressions
34
55
  end
35
56
 
36
57
  def readable_fields
@@ -1,18 +1,5 @@
1
1
  simple_item :register, :shadow do
2
2
  register_map do
3
- ShadowIndexEntry = Struct.new(:name, :value) do
4
- def initialize(name, value)
5
- self.name = name
6
- self.value = value && Integer(value)
7
- end
8
-
9
- def ==(other)
10
- return false unless name == other.name
11
- return true if [value, other.value].any?(&:nil?)
12
- value == other.value
13
- end
14
- end
15
-
16
3
  field :shadow?
17
4
  field :shadow_indexes
18
5
 
@@ -32,11 +19,24 @@ simple_item :register, :shadow do
32
19
  check_specific_value_index_values
33
20
  end
34
21
 
22
+ define_struct :shadow_index_entry, [:name, :value] do
23
+ def initialize(name, value)
24
+ self.name = name
25
+ self.value = value && Integer(value)
26
+ end
27
+
28
+ def ==(other)
29
+ return false unless name == other.name
30
+ return true if [value, other.value].any?(&:nil?)
31
+ value == other.value
32
+ end
33
+ end
34
+
35
35
  def parse_shadow_indexes(cell)
36
36
  return nil if cell.nil? || cell.empty?
37
37
  cell.split(/[,\n]/).map do |entry|
38
38
  if pattern_match(entry)
39
- ShadowIndexEntry.new(captures[0], captures[1])
39
+ shadow_index_entry.new(captures[0], captures[1])
40
40
  else
41
41
  error "invalid value for shadow index: #{cell.inspect}"
42
42
  end