rggen 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
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