rggen 0.3.2 → 0.3.3

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: 59adc06a285ad26b4dd71b5fccef26cceba4ee7f
4
- data.tar.gz: 2c08390336ae73726a619515cc9ed8a61d08eafa
3
+ metadata.gz: 78e4a09b9a969654a984d332dd8a275f9a77a554
4
+ data.tar.gz: 4880ac0a2c985415276dc82ad19bebdf95126dc3
5
5
  SHA512:
6
- metadata.gz: d2ac02e37af14189c9ea8aca80f2cbc8dd55e61f5b1ee80a754d0fbac301299e6b630d9eabd880c4114cb3f8634d19bb405205b467b9a4daa31a41e3683dadca
7
- data.tar.gz: ad4a174a3355412060839b9af4e38de1b79438eb001d52c809756c7addc357124beb1c8503700bb95f826751811f722dc0337ec6610536a5ca83debfe8177ac1
6
+ metadata.gz: 1de6c549f3e86452ebbd36f9cad45f2c05722f538d58f41448adecf41f764986a6ce936c929a6c1ab377f7deaac713e487136cd94edb0ab9fd2a5e185aa42032
7
+ data.tar.gz: 497e9ac09db980509796b0e341a116769f7183aead238866f46f0fc4b049a14e37c18465e8e66e6feee8fa568c374b3bbfc857b2dcd46a9704bdbff88b2f7cf6
data/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  # RgGen
7
7
 
8
8
  RgGen is a code generation tool for SoC designers.
9
- It will automatically generate source code for control registers in a SoC design, e.g. RLT, UVM RAL model, from its register map document.
9
+ It will automatically generate source code for control registers in a SoC design, e.g. RTL, UVM RAL model, from its register map document.
10
10
  Also RgGen is customizable so you can build your specific generate tool.
11
11
 
12
12
  ## Ruby
@@ -86,7 +86,7 @@ list_item :bit_field, :type do
86
86
  class_delegator :same_width
87
87
 
88
88
  build do |cell|
89
- @type = cell.to_sym.downcase
89
+ @type = cell
90
90
  end
91
91
 
92
92
  validate do
@@ -146,9 +146,14 @@ list_item :bit_field, :type do
146
146
 
147
147
  factory do
148
148
  def select_target_item(cell)
149
- type = cell.value.to_sym.downcase
150
- @target_items.fetch(type) do
151
- error "unknown bit field type: #{type}", cell
149
+ @target_items.fetch(cell.value) do
150
+ error "unknown bit field type: #{cell.value}", cell
151
+ end
152
+ end
153
+
154
+ def convert(cell)
155
+ @target_items.keys.find(proc { cell }) do |type|
156
+ type.to_sym.casecmp(cell.to_sym) == 0
152
157
  end
153
158
  end
154
159
  end
@@ -96,38 +96,48 @@ simple_item :register, :array do
96
96
  register_block.registers.take_while { |r| !register.equal?(r) }
97
97
  end
98
98
 
99
- generate_pre_code :module_item do |buffer|
100
- register.dimensions.each_with_index do |dimension, level|
101
- generate_for_begin_code(dimension, level, buffer)
102
- end if register.array?
99
+ generate_pre_code :module_item do |code|
100
+ if register.array?
101
+ generate_header(code)
102
+ generate_for_headers(code)
103
+ end
103
104
  end
104
105
 
105
- generate_post_code :module_item do |buffer|
106
- register.dimensions.size.times do
107
- generate_for_end_code(buffer)
108
- end if register.array?
106
+ generate_post_code :module_item do |code|
107
+ if register.array?
108
+ generate_for_footers(code)
109
+ generate_footer(code)
110
+ end
109
111
  end
110
112
 
111
- def generate_for_begin_code(dimension, level, buffer)
112
- buffer << generate_for_header(dimension, level)
113
- buffer << ' begin : '
114
- buffer << block_name(level)
115
- buffer << nl
116
- buffer.indent += 2
113
+ def generate_header(code)
114
+ code << "generate if (1) begin : g_#{register.name}" << nl
115
+ code.indent += 2
116
+ code << "genvar #{loop_variables.join(', ')};" << nl
117
117
  end
118
118
 
119
- def generate_for_end_code(buffer)
120
- buffer.indent -= 2
121
- buffer << 'end' << nl
119
+ def generate_for_headers(code)
120
+ register.dimensions.each_with_index do |dimension, level|
121
+ code << generate_for_header(dimension, level) << nl
122
+ code.indent += 2
123
+ end
122
124
  end
123
125
 
124
126
  def generate_for_header(dimension, level)
125
- genvar = loop_variable(level)
126
- "for (genvar #{genvar} = 0;#{genvar} < #{dimension};#{genvar}++)"
127
+ gv = loop_variable(level)
128
+ "for (#{gv} = 0;#{gv} < #{dimension};#{gv}++) begin : g"
129
+ end
130
+
131
+ def generate_for_footers(code)
132
+ register.dimensions.size.times do
133
+ code.indent -= 2
134
+ code << :end << nl
135
+ end
127
136
  end
128
137
 
129
- def block_name(level)
130
- "gen_#{register.name}_#{level}"
138
+ def generate_footer(code)
139
+ code.indent -= 2
140
+ code << :end << space << :endgenerate << nl
131
141
  end
132
142
  end
133
143
  end
@@ -1,4 +1,17 @@
1
1
  list_item :register_block, :host_if, :apb do
2
+ configuration do
3
+ validate do
4
+ if configuration.address_width > 32
5
+ error 'apb supports 32 or less bits address width only' \
6
+ ": #{configuration.address_width}"
7
+ end
8
+ if configuration.data_width > 32
9
+ error 'apb supports 32 or less bits data width only' \
10
+ ": #{configuration.data_width}"
11
+ end
12
+ end
13
+ end
14
+
2
15
  rtl do
3
16
  build do
4
17
  group(:apb) do
@@ -0,0 +1,37 @@
1
+ rggen_host_if_axi4lite #(
2
+ .DATA_WIDTH (<%= data_width %>),
3
+ .HOST_ADDRESS_WIDTH (<%= address_width %>),
4
+ .LOCAL_ADDRESS_WIDTH (<%= local_address_width %>),
5
+ .WRITE_PRIORITY (<%= write_priority %>)
6
+ ) u_host_if (
7
+ .clk (<%= clock %>),
8
+ .rst_n (<%= reset %>),
9
+ .i_awvalid (<%= axi4lite.awvalid %>),
10
+ .o_awready (<%= axi4lite.awready %>),
11
+ .i_awaddr (<%= axi4lite.awaddr %>),
12
+ .i_awprot (<%= axi4lite.awprot %>),
13
+ .i_wvalid (<%= axi4lite.wvalid %>),
14
+ .o_wready (<%= axi4lite.wready %>),
15
+ .i_wdata (<%= axi4lite.wdata %>),
16
+ .i_wstrb (<%= axi4lite.wstrb %>),
17
+ .o_bvalid (<%= axi4lite.bvalid %>),
18
+ .i_bready (<%= axi4lite.bready %>),
19
+ .o_bresp (<%= axi4lite.bresp %>),
20
+ .i_arvalid (<%= axi4lite.arvalid %>),
21
+ .o_arready (<%= axi4lite.arready %>),
22
+ .i_araddr (<%= axi4lite.araddr %>),
23
+ .i_arprot (<%= axi4lite.arprot %>),
24
+ .o_rvalid (<%= axi4lite.rvalid %>),
25
+ .i_rready (<%= axi4lite.rready %>),
26
+ .o_rdata (<%= axi4lite.rdata %>),
27
+ .o_rresp (<%= axi4lite.rresp %>),
28
+ .o_command_valid (<%= host_if.command_valid %>),
29
+ .o_write (<%= host_if.write %>),
30
+ .o_read (<%= host_if.read %>),
31
+ .o_address (<%= host_if.address %>),
32
+ .o_write_data (<%= host_if.write_data %>),
33
+ .o_write_mask (<%= host_if.write_mask %>),
34
+ .i_response_ready (<%= host_if.response_ready %>),
35
+ .i_read_data (<%= host_if.read_data %>),
36
+ .i_status (<%= host_if.status %>)
37
+ );
@@ -0,0 +1,46 @@
1
+ list_item :register_block, :host_if, :axi4lite do
2
+ configuration do
3
+ validate do
4
+ unless [32, 64].include?(configuration.data_width)
5
+ error 'axi4lite supports either 32 or 64 bits data width only' \
6
+ ": #{configuration.data_width}"
7
+ end
8
+ end
9
+ end
10
+
11
+ rtl do
12
+ delegate [
13
+ :address_width, :data_width, :byte_width
14
+ ] => :configuration
15
+ delegate [
16
+ :local_address_width, :clock, :reset
17
+ ] => :register_block
18
+
19
+ build do
20
+ parameter :write_priority, name: 'WRITE_PRIORITY', default: 1
21
+ group :axi4lite do
22
+ input :awvalid, name: 'i_awvalid', width: 1
23
+ output :awready, name: 'o_awready', width: 1
24
+ input :awaddr , name: 'i_awaddr' , width: address_width
25
+ input :awprot , name: 'i_awprot' , width: 3
26
+ input :wvalid , name: 'i_wvalid' , width: 1
27
+ output :wready , name: 'o_wready' , width: 1
28
+ input :wdata , name: 'i_wdata' , width: data_width
29
+ input :wstrb , name: 'i_wstrb' , width: byte_width
30
+ output :bvalid , name: 'o_bvalid' , width: 1
31
+ input :bready , name: 'i_bready' , width: 1
32
+ output :bresp , name: 'o_bresp' , width: 2
33
+ input :arvalid, name: 'i_arvalid', width: 1
34
+ output :arready, name: 'o_arready', width: 1
35
+ input :araddr , name: 'i_araddr' , width: address_width
36
+ input :arprot , name: 'i_arprot' , width: 3
37
+ output :rvalid , name: 'o_rvalid' , width: 1
38
+ input :rready , name: 'i_rready' , width: 1
39
+ output :rdata , name: 'o_rdata' , width: data_width
40
+ output :rresp , name: 'o_rresp' , width: 2
41
+ end
42
+ end
43
+
44
+ generate_code_from_template :module_item
45
+ end
46
+ end
@@ -4,16 +4,34 @@ list_item :register_block, :host_if do
4
4
  end
5
5
 
6
6
  configuration do
7
- item_class do
7
+ item_base do
8
8
  field :host_if do
9
9
  @host_if || shared_context.enabled_host_ifs.first
10
10
  end
11
11
 
12
12
  build do |value|
13
- @host_if = shared_context.enabled_host_ifs.find do |host_if|
13
+ @host_if = value
14
+ end
15
+ end
16
+
17
+ default_item do
18
+ end
19
+
20
+ factory do
21
+ def select_target_item(value)
22
+ @target_items[value]
23
+ end
24
+
25
+ def convert(value)
26
+ find_host_if(value) do
27
+ error "unknown host interface: #{value}"
28
+ end
29
+ end
30
+
31
+ def find_host_if(value, &ifnone)
32
+ shared_context.enabled_host_ifs.find(ifnone) do |host_if|
14
33
  host_if.to_sym.casecmp(value.to_sym) == 0
15
34
  end
16
- error "unknown host interface: #{value}" if @host_if.nil?
17
35
  end
18
36
  end
19
37
  end
@@ -43,6 +43,7 @@ require_relative 'builtins/register_block/byte_size'
43
43
  require_relative 'builtins/register_block/clock_reset'
44
44
  require_relative 'builtins/register_block/host_if'
45
45
  require_relative 'builtins/register_block/apb'
46
+ require_relative 'builtins/register_block/axi4lite'
46
47
  require_relative 'builtins/register_block/module_definition'
47
48
  require_relative 'builtins/register_block/name'
48
49
  require_relative 'builtins/register_block/ral_package_definition'
@@ -0,0 +1,11 @@
1
+ module RgGen
2
+ module Configuration
3
+ class Item < InputBase::Item
4
+ include RaiseError
5
+
6
+ def configuration
7
+ @owner
8
+ end
9
+ end
10
+ end
11
+ end
@@ -4,9 +4,16 @@ module RgGen
4
4
  include RaiseError
5
5
 
6
6
  def create(configuration, data = nil)
7
- item = create_item(configuration, data)
8
- item.build(data) unless data.nil?
9
- item
7
+ data &&= convert(data)
8
+ create_item(configuration, data).tap do |item|
9
+ item.build(data) unless data.nil?
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def convert(data)
16
+ data
10
17
  end
11
18
  end
12
19
  end
@@ -4,7 +4,7 @@ module RgGen
4
4
  entry do
5
5
  component_class InputBase::Component
6
6
  component_factory ConfigurationFactory
7
- item_base InputBase::Item, include: RaiseError
7
+ item_base Item
8
8
  item_factory ItemFactory
9
9
  end
10
10
 
@@ -14,8 +14,10 @@ module RgGen
14
14
 
15
15
  def build(configuration, cell)
16
16
  @configuration = configuration
17
- @position = cell.position
18
- super(cell.value)
17
+ unless cell.nil?
18
+ @position = cell.position
19
+ super(cell.value)
20
+ end
19
21
  end
20
22
  end
21
23
  end
@@ -4,9 +4,22 @@ module RgGen
4
4
  include RaiseError
5
5
 
6
6
  def create(component, configuration, cell = nil)
7
- item = create_item(component, cell)
8
- item.build(configuration, cell) unless cell.nil?
9
- item
7
+ convert_cell_value(cell)
8
+ create_item(component, cell).tap do |item|
9
+ item.build(configuration, cell)
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def convert_cell_value(cell)
16
+ return if cell.nil?
17
+ return if cell.empty?
18
+ cell.value = convert(cell.value)
19
+ end
20
+
21
+ def convert(cell)
22
+ cell
10
23
  end
11
24
  end
12
25
  end
@@ -1,4 +1,5 @@
1
1
  require_relative 'core_components/configuration/raise_error'
2
+ require_relative 'core_components/configuration/item'
2
3
  require_relative 'core_components/configuration/configuration_factory'
3
4
  require_relative 'core_components/configuration/item_factory'
4
5
  require_relative 'core_components/configuration/setup'
data/lib/rggen/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module RgGen
2
2
  MAJOR = 0
3
3
  MINOR = 3
4
- TEENY = 2
4
+ TEENY = 3
5
5
  VERSION = "#{MAJOR}.#{MINOR}.#{TEENY}".freeze
6
6
  end
data/rtl/compile.f CHANGED
@@ -1,4 +1,5 @@
1
1
  +libext+.sv
2
+ +incdir+${RGGEN_HOME}/rtl/register_block
2
3
  -y ${RGGEN_HOME}/rtl/bit_field
3
4
  -y ${RGGEN_HOME}/rtl/register
4
5
  -y ${RGGEN_HOME}/rtl/register_block
@@ -23,27 +23,35 @@ module rggen_address_decoder #(
23
23
 
24
24
  assign match = (match_address && match_shadow_index) ? 1'b1 : 1'b0;
25
25
 
26
- if (START_ADDRESS == END_ADDRESS) begin
27
- assign match_address = (i_address == START_ADDRESS) ? 1'b1 : 1'b0;
28
- end
29
- else begin
30
- assign match_address = (i_address inside {[START_ADDRESS:END_ADDRESS]}) ? 1'b1 : 1'b0;
31
- end
26
+ generate
27
+ if (START_ADDRESS == END_ADDRESS) begin
28
+ assign match_address = (i_address == START_ADDRESS) ? 1'b1 : 1'b0;
29
+ end
30
+ else begin
31
+ assign match_address = (
32
+ (i_address >= START_ADDRESS) && (i_address <= END_ADDRESS)
33
+ ) ? 1'b1 : 1'b0;
34
+ end
35
+ endgenerate
32
36
 
33
- if (USE_SHADOW_INDEX) begin
34
- assign match_shadow_index = (i_shadow_index == SHADOW_INDEX_VALUE) ? 1'b1 : 1'b0;
35
- end
36
- else begin
37
- assign match_shadow_index = 1'b1;
38
- end
37
+ generate
38
+ if (USE_SHADOW_INDEX) begin
39
+ assign match_shadow_index = (i_shadow_index == SHADOW_INDEX_VALUE) ? 1'b1 : 1'b0;
40
+ end
41
+ else begin
42
+ assign match_shadow_index = 1'b1;
43
+ end
44
+ endgenerate
39
45
 
40
- if (READ_ONLY) begin
41
- assign o_select = (match && i_read) ? 1'b1 : 1'b0;
42
- end
43
- else if (WRITE_ONLY) begin
44
- assign o_select = (match && i_write) ? 1'b1 : 1'b0;
45
- end
46
- else begin
47
- assign o_select = match;
48
- end
46
+ generate
47
+ if (READ_ONLY) begin
48
+ assign o_select = (match && i_read) ? 1'b1 : 1'b0;
49
+ end
50
+ else if (WRITE_ONLY) begin
51
+ assign o_select = (match && i_write) ? 1'b1 : 1'b0;
52
+ end
53
+ else begin
54
+ assign o_select = match;
55
+ end
56
+ endgenerate
49
57
  endmodule
@@ -25,6 +25,8 @@ module rggen_host_if_apb #(
25
25
  input [DATA_WIDTH-1:0] i_read_data,
26
26
  input [1:0] i_status
27
27
  );
28
+ `include "rggen_host_if_common.svh"
29
+
28
30
  assign o_pready = i_response_ready;
29
31
  assign o_prdata = i_read_data;
30
32
  assign o_pslverr = i_status[0];
@@ -34,7 +36,5 @@ module rggen_host_if_apb #(
34
36
  assign o_read = ~i_pwrite;
35
37
  assign o_address = i_paddr[LOCAL_ADDRESS_WIDTH-1:0];
36
38
  assign o_write_data = i_pwdata;
37
- for (genvar i = 0;i < DATA_WIDTH / 8;i++) begin
38
- assign o_write_mask[i*8+:8] = {8{i_pstrb[i]}};
39
- end
39
+ assign o_write_mask = get_write_mask(i_pstrb);
40
40
  endmodule
@@ -0,0 +1,251 @@
1
+ module rggen_host_if_axi4lite #(
2
+ parameter DATA_WIDTH = 32,
3
+ parameter HOST_ADDRESS_WIDTH = 16,
4
+ parameter LOCAL_ADDRESS_WIDTH = 16,
5
+ parameter WRITE_PRIORITY = 1
6
+ )(
7
+ input clk,
8
+ input rst_n,
9
+ input i_awvalid,
10
+ output o_awready,
11
+ input [HOST_ADDRESS_WIDTH-1:0] i_awaddr,
12
+ input [2:0] i_awprot,
13
+ input i_wvalid,
14
+ output o_wready,
15
+ input [DATA_WIDTH-1:0] i_wdata,
16
+ input [DATA_WIDTH/8-1:0] i_wstrb,
17
+ output o_bvalid,
18
+ input i_bready,
19
+ output [1:0] o_bresp,
20
+ input i_arvalid,
21
+ output o_arready,
22
+ input [HOST_ADDRESS_WIDTH-1:0] i_araddr,
23
+ input [2:0] i_arprot,
24
+ output o_rvalid,
25
+ input i_rready,
26
+ output [DATA_WIDTH-1:0] o_rdata,
27
+ output [1:0] o_rresp,
28
+ output o_command_valid,
29
+ output o_write,
30
+ output o_read,
31
+ output [LOCAL_ADDRESS_WIDTH-1:0] o_address,
32
+ output [DATA_WIDTH-1:0] o_write_data,
33
+ output [DATA_WIDTH-1:0] o_write_mask,
34
+ input i_response_ready,
35
+ input [DATA_WIDTH-1:0] i_read_data,
36
+ input [1:0] i_status
37
+ );
38
+ `include "rggen_host_if_common.svh"
39
+
40
+ typedef enum logic [5:0] {
41
+ IDLE = 6'b000001,
42
+ WAIT_WDATA = 6'b000010,
43
+ WRITE_IN_PROGRESS = 6'b000100,
44
+ WAIT_BRESP_READY = 6'b001000,
45
+ READ_IN_PROGRESS = 6'b010000,
46
+ WAIT_RDATA_READY = 6'b100000
47
+ } e_state;
48
+
49
+ typedef enum logic [1:0] {
50
+ OKAY = 2'b00,
51
+ EXOKAY = 2'b01,
52
+ SLVERR = 2'b10,
53
+ DECERR = 2'b11
54
+ } e_resp;
55
+
56
+ function e_resp get_resp(logic [1:0] status);
57
+ case (1'b1)
58
+ status[0]: return SLVERR;
59
+ status[1]: return EXOKAY;
60
+ default: return OKAY;
61
+ endcase
62
+ endfunction
63
+
64
+ e_state state;
65
+ logic awready;
66
+ logic wready;
67
+ logic bvalid;
68
+ e_resp bresp;
69
+ logic arready;
70
+ logic rvalid;
71
+ logic [DATA_WIDTH-1:0] rdata;
72
+ e_resp rresp;
73
+ logic awack;
74
+ logic wack;
75
+ logic back;
76
+ logic arack;
77
+ logic rack;
78
+ logic command_valid;
79
+ logic local_done;
80
+ logic [LOCAL_ADDRESS_WIDTH-1:0] address;
81
+ logic [DATA_WIDTH-1:0] write_data;
82
+ logic [DATA_WIDTH-1:0] write_mask;
83
+
84
+ //--------------------------------------------------------------
85
+ // State machine
86
+ //--------------------------------------------------------------
87
+ always_ff @(posedge clk or negedge rst_n) begin
88
+ if (!rst_n) begin
89
+ state <= IDLE;
90
+ end
91
+ else begin
92
+ unique case (state)
93
+ IDLE: begin
94
+ if (awack && wack) begin
95
+ state <= WRITE_IN_PROGRESS;
96
+ end
97
+ else if (awack) begin
98
+ state <= WAIT_WDATA;
99
+ end
100
+ else if (arack) begin
101
+ state <= READ_IN_PROGRESS;
102
+ end
103
+ end
104
+ WAIT_WDATA: begin
105
+ if (wack) begin
106
+ state <= WRITE_IN_PROGRESS;
107
+ end
108
+ end
109
+ WRITE_IN_PROGRESS: begin
110
+ if (local_done) begin
111
+ state <= WAIT_BRESP_READY;
112
+ end
113
+ end
114
+ WAIT_BRESP_READY: begin
115
+ if (back) begin
116
+ state <= IDLE;
117
+ end
118
+ end
119
+ READ_IN_PROGRESS: begin
120
+ if (local_done) begin
121
+ state <= WAIT_RDATA_READY;
122
+ end
123
+ end
124
+ WAIT_RDATA_READY: begin
125
+ if (rack) begin
126
+ state <= IDLE;
127
+ end
128
+ end
129
+ default: begin
130
+ state <= IDLE;
131
+ end
132
+ endcase
133
+ end
134
+ end
135
+
136
+ //--------------------------------------------------------------
137
+ // AXI4-Lite
138
+ //--------------------------------------------------------------
139
+ assign o_awready = awready;
140
+ assign o_wready = wready;
141
+ assign o_bvalid = bvalid;
142
+ assign o_bresp = bresp;
143
+ assign o_arready = arready;
144
+ assign o_rvalid = rvalid;
145
+ assign o_rdata = rdata;
146
+ assign o_rresp = rresp;
147
+
148
+ assign awack = i_awvalid & awready;
149
+ assign wack = i_wvalid & wready;
150
+ assign back = bvalid & i_bready;
151
+ assign arack = i_arvalid & arready;
152
+ assign rack = rvalid & i_rready;
153
+
154
+ generate
155
+ if (WRITE_PRIORITY) begin
156
+ assign awready = state[0];
157
+ assign wready = (state[0] || state[1]) ? 1'b1 : 1'b0;
158
+ assign bvalid = state[3];
159
+ assign arready = (state[0] && (!i_awvalid)) ? 1'b1 : 1'b0;
160
+ assign rvalid = state[5];
161
+ end
162
+ else begin
163
+ assign awready = (state[0] && (!i_arvalid)) ? 1'b1 : 1'b0;
164
+ assign wready = ((state[0] && (!i_arvalid)) || state[1]) ? 1'b1 : 1'b0;
165
+ assign bvalid = state[3];
166
+ assign arready = state[0];
167
+ assign rvalid = state[5];
168
+ end
169
+ endgenerate
170
+
171
+ always_ff @(posedge clk or negedge rst_n) begin
172
+ if (!rst_n) begin
173
+ bresp <= OKAY;
174
+ end
175
+ else if (state[2] && local_done) begin
176
+ bresp <= get_resp(i_status);
177
+ end
178
+ else if (back) begin
179
+ bresp <= OKAY;
180
+ end
181
+ end
182
+
183
+ always_ff @(posedge clk or negedge rst_n) begin
184
+ if (!rst_n) begin
185
+ rdata <= '0;
186
+ rresp <= OKAY;
187
+ end
188
+ else if (state[4] && local_done) begin
189
+ rdata <= i_read_data;
190
+ rresp <= get_resp(i_status);
191
+ end
192
+ else if (rack) begin
193
+ rdata <= '0;
194
+ rresp <= OKAY;
195
+ end
196
+ end
197
+
198
+ //--------------------------------------------------------------
199
+ // Local bus
200
+ //--------------------------------------------------------------
201
+ assign o_command_valid = command_valid;
202
+ assign o_address = address;
203
+ assign o_write = state[2];
204
+ assign o_read = state[4];
205
+ assign o_write_data = write_data;
206
+ assign o_write_mask = write_mask;
207
+
208
+ assign local_done = command_valid & i_response_ready;
209
+
210
+ always_ff @(posedge clk or negedge rst_n) begin
211
+ if (!rst_n) begin
212
+ command_valid <= 1'b0;
213
+ end
214
+ else if (wack || arack) begin
215
+ command_valid <= 1'b1;
216
+ end
217
+ else if (local_done) begin
218
+ command_valid <= 1'b0;
219
+ end
220
+ end
221
+
222
+ always_ff @(posedge clk or negedge rst_n) begin
223
+ if (!rst_n) begin
224
+ address <= '0;
225
+ end
226
+ else if (awack) begin
227
+ address <= i_awaddr[LOCAL_ADDRESS_WIDTH-1:0];
228
+ end
229
+ else if (arack) begin
230
+ address <= i_araddr[LOCAL_ADDRESS_WIDTH-1:0];
231
+ end
232
+ else if (local_done) begin
233
+ address <= '0;
234
+ end
235
+ end
236
+
237
+ always_ff @(posedge clk or negedge rst_n) begin
238
+ if (!rst_n) begin
239
+ write_data <= '0;
240
+ write_mask <= '0;
241
+ end
242
+ else if (wack) begin
243
+ write_data <= i_wdata;
244
+ write_mask <= get_write_mask(i_wstrb);
245
+ end
246
+ else if (local_done) begin
247
+ write_data <= '0;
248
+ write_mask <= '0;
249
+ end
250
+ end
251
+ endmodule
@@ -0,0 +1,9 @@
1
+ function automatic logic [DATA_WIDTH-1:0] get_write_mask(
2
+ input [DATA_WIDTH/8-1:0] strobe
3
+ );
4
+ logic [DATA_WIDTH-1:0] write_mask;
5
+ for (int i = 0;i < $size(strobe);i++) begin
6
+ write_mask[i*8+:8] = {8{strobe[i]}};
7
+ end
8
+ return write_mask;
9
+ endfunction
@@ -57,26 +57,27 @@ module rggen_response_mux #(
57
57
  assign o_read_data = read_data;
58
58
  always_ff @(posedge clk or negedge rst_n) begin
59
59
  if (!rst_n) begin
60
- read_data <= {DATA_WIDTH{1'b0}};
60
+ read_data <= '0;
61
61
  end
62
62
  else if (response_valid && i_read) begin
63
- read_data <= selected_data;
63
+ read_data <= select_read_data(
64
+ .select (i_register_select ),
65
+ .read_data (i_register_read_data )
66
+ );
64
67
  end
65
68
  else begin
66
- read_data <= {DATA_WIDTH{1'b0}};
69
+ read_data <= '0;
67
70
  end
68
71
  end
69
72
 
70
- if (TOTAL_REGISTERS > 1) begin
71
- for (genvar i = 0;i < DATA_WIDTH;i++) begin
72
- logic [TOTAL_REGISTERS-1:0] temp;
73
- assign selected_data[i] = |temp;
74
- for (genvar j = 0;j < TOTAL_REGISTERS;j++) begin
75
- assign temp[j] = i_register_select[j] & i_register_read_data[j][i];
76
- end
73
+ function automatic logic [DATA_WIDTH-1:0] select_read_data(
74
+ input logic [TOTAL_REGISTERS-1:0] select,
75
+ input logic [DATA_WIDTH-1:0] read_data[TOTAL_REGISTERS]
76
+ );
77
+ logic [DATA_WIDTH-1:0] masked_read_data[TOTAL_REGISTERS];
78
+ for (int i = 0;i < TOTAL_REGISTERS;i++) begin
79
+ masked_read_data[i] = {DATA_WIDTH{select[i]}} & read_data[i];
77
80
  end
78
- end
79
- else begin
80
- assign selected_data = i_register_read_data[0];
81
- end
81
+ return masked_read_data.or();
82
+ endfunction
82
83
  endmodule
data/sample/sample_0.sv CHANGED
@@ -211,75 +211,81 @@ module sample_0 (
211
211
  );
212
212
  assign register_read_data[3] = {bit_field_3_0_value};
213
213
  assign bit_field_3_0_value = i_bit_field_3_0;
214
- for (genvar g_i = 0;g_i < 4;g_i++) begin : gen_register_4_0
215
- rggen_address_decoder #(
216
- .READABLE (1),
217
- .WRITABLE (1),
218
- .ADDRESS_WIDTH (6),
219
- .START_ADDRESS (6'h04 + g_i),
220
- .END_ADDRESS (6'h04 + g_i),
221
- .USE_SHADOW_INDEX (0),
222
- .SHADOW_INDEX_WIDTH (1),
223
- .SHADOW_INDEX_VALUE (1'h0)
224
- ) u_register_4_address_decoder (
225
- .i_read (read),
226
- .i_write (write),
227
- .i_address (address[7:2]),
228
- .i_shadow_index (1'h0),
229
- .o_select (register_select[4+g_i])
230
- );
231
- assign register_read_data[4+g_i] = {bit_field_4_0_value[g_i], bit_field_4_1_value[g_i]};
232
- assign bit_field_4_0_value[g_i] = i_bit_field_4_0[g_i];
233
- assign o_bit_field_4_1[g_i] = bit_field_4_1_value[g_i];
234
- rggen_bit_field_rw #(
235
- .WIDTH (16),
236
- .INITIAL_VALUE (16'h0000)
237
- ) u_bit_field_4_1 (
238
- .clk (clk),
239
- .rst_n (rst_n),
240
- .i_command_valid (command_valid),
241
- .i_select (register_select[4+g_i]),
242
- .i_write (write),
243
- .i_write_data (write_data[15:0]),
244
- .i_write_mask (write_mask[15:0]),
245
- .o_value (bit_field_4_1_value[g_i])
246
- );
247
- end
248
- for (genvar g_i = 0;g_i < 2;g_i++) begin : gen_register_5_0
249
- for (genvar g_j = 0;g_j < 4;g_j++) begin : gen_register_5_1
250
- assign register_5_shadow_index[g_i][g_j] = {bit_field_2_1_value, bit_field_0_0_value, bit_field_0_1_value};
214
+ generate if (1) begin : g_register_4
215
+ genvar g_i;
216
+ for (g_i = 0;g_i < 4;g_i++) begin : g
251
217
  rggen_address_decoder #(
252
218
  .READABLE (1),
253
219
  .WRITABLE (1),
254
220
  .ADDRESS_WIDTH (6),
255
- .START_ADDRESS (6'h08),
256
- .END_ADDRESS (6'h08),
257
- .USE_SHADOW_INDEX (1),
258
- .SHADOW_INDEX_WIDTH (33),
259
- .SHADOW_INDEX_VALUE ({1'h1, g_i[15:0], g_j[15:0]})
260
- ) u_register_5_address_decoder (
221
+ .START_ADDRESS (6'h04 + g_i),
222
+ .END_ADDRESS (6'h04 + g_i),
223
+ .USE_SHADOW_INDEX (0),
224
+ .SHADOW_INDEX_WIDTH (1),
225
+ .SHADOW_INDEX_VALUE (1'h0)
226
+ ) u_register_4_address_decoder (
261
227
  .i_read (read),
262
228
  .i_write (write),
263
229
  .i_address (address[7:2]),
264
- .i_shadow_index (register_5_shadow_index[g_i][g_j]),
265
- .o_select (register_select[8+4*g_i+g_j])
230
+ .i_shadow_index (1'h0),
231
+ .o_select (register_select[4+g_i])
266
232
  );
267
- assign register_read_data[8+4*g_i+g_j] = {bit_field_5_0_value[g_i][g_j], bit_field_5_1_value[g_i][g_j]};
268
- assign bit_field_5_0_value[g_i][g_j] = i_bit_field_5_0[g_i][g_j];
269
- assign o_bit_field_5_1[g_i][g_j] = bit_field_5_1_value[g_i][g_j];
233
+ assign register_read_data[4+g_i] = {bit_field_4_0_value[g_i], bit_field_4_1_value[g_i]};
234
+ assign bit_field_4_0_value[g_i] = i_bit_field_4_0[g_i];
235
+ assign o_bit_field_4_1[g_i] = bit_field_4_1_value[g_i];
270
236
  rggen_bit_field_rw #(
271
237
  .WIDTH (16),
272
238
  .INITIAL_VALUE (16'h0000)
273
- ) u_bit_field_5_1 (
239
+ ) u_bit_field_4_1 (
274
240
  .clk (clk),
275
241
  .rst_n (rst_n),
276
242
  .i_command_valid (command_valid),
277
- .i_select (register_select[8+4*g_i+g_j]),
243
+ .i_select (register_select[4+g_i]),
278
244
  .i_write (write),
279
245
  .i_write_data (write_data[15:0]),
280
246
  .i_write_mask (write_mask[15:0]),
281
- .o_value (bit_field_5_1_value[g_i][g_j])
247
+ .o_value (bit_field_4_1_value[g_i])
282
248
  );
283
249
  end
284
- end
250
+ end endgenerate
251
+ generate if (1) begin : g_register_5
252
+ genvar g_i, g_j;
253
+ for (g_i = 0;g_i < 2;g_i++) begin : g
254
+ for (g_j = 0;g_j < 4;g_j++) begin : g
255
+ assign register_5_shadow_index[g_i][g_j] = {bit_field_2_1_value, bit_field_0_0_value, bit_field_0_1_value};
256
+ rggen_address_decoder #(
257
+ .READABLE (1),
258
+ .WRITABLE (1),
259
+ .ADDRESS_WIDTH (6),
260
+ .START_ADDRESS (6'h08),
261
+ .END_ADDRESS (6'h08),
262
+ .USE_SHADOW_INDEX (1),
263
+ .SHADOW_INDEX_WIDTH (33),
264
+ .SHADOW_INDEX_VALUE ({1'h1, g_i[15:0], g_j[15:0]})
265
+ ) u_register_5_address_decoder (
266
+ .i_read (read),
267
+ .i_write (write),
268
+ .i_address (address[7:2]),
269
+ .i_shadow_index (register_5_shadow_index[g_i][g_j]),
270
+ .o_select (register_select[8+4*g_i+g_j])
271
+ );
272
+ assign register_read_data[8+4*g_i+g_j] = {bit_field_5_0_value[g_i][g_j], bit_field_5_1_value[g_i][g_j]};
273
+ assign bit_field_5_0_value[g_i][g_j] = i_bit_field_5_0[g_i][g_j];
274
+ assign o_bit_field_5_1[g_i][g_j] = bit_field_5_1_value[g_i][g_j];
275
+ rggen_bit_field_rw #(
276
+ .WIDTH (16),
277
+ .INITIAL_VALUE (16'h0000)
278
+ ) u_bit_field_5_1 (
279
+ .clk (clk),
280
+ .rst_n (rst_n),
281
+ .i_command_valid (command_valid),
282
+ .i_select (register_select[8+4*g_i+g_j]),
283
+ .i_write (write),
284
+ .i_write_data (write_data[15:0]),
285
+ .i_write_mask (write_mask[15:0]),
286
+ .o_value (bit_field_5_1_value[g_i][g_j])
287
+ );
288
+ end
289
+ end
290
+ end endgenerate
285
291
  endmodule
data/setup/default.rb CHANGED
@@ -4,7 +4,7 @@ enable :register , [:offset_address, :name, :array, :shadow, :accessibility
4
4
  enable :bit_field , [:bit_assignment, :name, :type, :initial_value, :reference]
5
5
  enable :bit_field , :type, [:rw, :ro, :reserved]
6
6
  enable :register_block, [:module_definition, :signal_declarations, :clock_reset, :host_if, :response_mux]
7
- enable :register_block, :host_if, [:apb]
7
+ enable :register_block, :host_if, [:apb, :axi4lite]
8
8
  enable :register , [:address_decoder, :read_data]
9
9
  enable :register_block, [:ral_package_definition, :block_model_definition, :reg_model_declarations, :block_model_constructor, :reg_model_creator, :block_model_default_map_creator]
10
10
  enable :register , [:reg_model_definition, :field_model_declarations, :reg_model_constructor, :field_model_creator, :shadow_index_configurator, :reg_model_declaration, :reg_model_creation]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rggen
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Taichi Ishitani
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-15 00:00:00.000000000 Z
11
+ date: 2016-04-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: baby_erubis
@@ -110,7 +110,7 @@ dependencies:
110
110
  version: '0.35'
111
111
  description: |2
112
112
  RgGen is a code generation tool for SoC designers.
113
- It will automatically generate source code for control registers in a SoC design, e.g. RLT, UVM RAL model, from its register map document.
113
+ It will automatically generate source code for control registers in a SoC design, e.g. RTL, UVM RAL model, from its register map document.
114
114
  Also RgGen is customizable so you can build your specific generate tool.
115
115
  email:
116
116
  - taichi730@gmail.com
@@ -119,8 +119,6 @@ executables:
119
119
  extensions: []
120
120
  extra_rdoc_files: []
121
121
  files:
122
- - ".rubocop.yml"
123
- - ".rubocop_todo.yml"
124
122
  - CODE_OF_CONDUCT.md
125
123
  - LICENSE.txt
126
124
  - README.md
@@ -179,6 +177,8 @@ files:
179
177
  - lib/rggen/builtins/register/uniqueness_validator.rb
180
178
  - lib/rggen/builtins/register_block/apb.erb
181
179
  - lib/rggen/builtins/register_block/apb.rb
180
+ - lib/rggen/builtins/register_block/axi4lite.erb
181
+ - lib/rggen/builtins/register_block/axi4lite.rb
182
182
  - lib/rggen/builtins/register_block/base_address.rb
183
183
  - lib/rggen/builtins/register_block/block_model_constructor.rb
184
184
  - lib/rggen/builtins/register_block/block_model_default_map_creator.rb
@@ -197,6 +197,7 @@ files:
197
197
  - lib/rggen/commands.rb
198
198
  - lib/rggen/core_components.rb
199
199
  - lib/rggen/core_components/configuration/configuration_factory.rb
200
+ - lib/rggen/core_components/configuration/item.rb
200
201
  - lib/rggen/core_components/configuration/item_factory.rb
201
202
  - lib/rggen/core_components/configuration/raise_error.rb
202
203
  - lib/rggen/core_components/configuration/setup.rb
@@ -253,11 +254,12 @@ files:
253
254
  - ral/rggen_ral_pkg.sv
254
255
  - ral/rggen_ral_reg.svh
255
256
  - ral/rggen_ral_shadow_reg.svh
256
- - rggen.gemspec
257
257
  - rtl/bit_field/rggen_bit_field_rw.sv
258
258
  - rtl/compile.f
259
259
  - rtl/register/rggen_address_decoder.sv
260
260
  - rtl/register_block/rggen_host_if_apb.sv
261
+ - rtl/register_block/rggen_host_if_axi4lite.sv
262
+ - rtl/register_block/rggen_host_if_common.svh
261
263
  - rtl/register_block/rggen_response_mux.sv
262
264
  - sample/sample.csv
263
265
  - sample/sample.json
@@ -270,7 +272,7 @@ files:
270
272
  - sample/sample_1_ral_pkg.sv
271
273
  - sample/sample_setup.rb
272
274
  - setup/default.rb
273
- homepage: ''
275
+ homepage: https://github.com/taichi-ishitani/rggen
274
276
  licenses:
275
277
  - MIT
276
278
  metadata: {}
data/.rubocop.yml DELETED
@@ -1,7 +0,0 @@
1
- inherit_from: .rubocop_todo.yml
2
-
3
- AllCops:
4
- Exclude:
5
- - 'sample/*'
6
- - 'setup/*'
7
- - 'spec/**/*'
data/.rubocop_todo.yml DELETED
@@ -1,91 +0,0 @@
1
- # This configuration was generated by
2
- # `rubocop --auto-gen-config`
3
- # on 2015-12-27 19:46:19 +0900 using RuboCop version 0.35.1.
4
- # The point is for the user to remove these configuration records
5
- # one by one as the offenses are removed from the code base.
6
- # Note that changes in the inspected code, or installation of new
7
- # versions of RuboCop, may require this file to be generated again.
8
-
9
- # Offense count: 2
10
- Lint/FormatParameterMismatch:
11
- Exclude:
12
- - 'lib/rgen/core_components/rtl/item.rb'
13
-
14
- # Offense count: 3
15
- Metrics/AbcSize:
16
- Max: 18
17
-
18
- # Offense count: 1
19
- Metrics/CyclomaticComplexity:
20
- Max: 7
21
-
22
- # Offense count: 8
23
- # Configuration parameters: AllowURI, URISchemes.
24
- Metrics/LineLength:
25
- Max: 142
26
-
27
- # Offense count: 1
28
- # Configuration parameters: CountComments.
29
- Metrics/MethodLength:
30
- Max: 11
31
-
32
- # Offense count: 72
33
- # Configuration parameters: Exclude.
34
- Style/Documentation:
35
- Enabled: false
36
-
37
- # Offense count: 56
38
- # Cop supports --auto-correct.
39
- # Configuration parameters: AllowForAlignment.
40
- Style/ExtraSpacing:
41
- Enabled: false
42
-
43
- # Offense count: 2
44
- # Cop supports --auto-correct.
45
- # Configuration parameters: EnforcedStyle, SupportedStyles, UseHashRocketsWithSymbolValues.
46
- Style/HashSyntax:
47
- Enabled: false
48
-
49
- # Offense count: 33
50
- # Cop supports --auto-correct.
51
- Style/SingleSpaceBeforeFirstArg:
52
- Exclude:
53
- - 'lib/rgen/builtins/register_block/apb.rb'
54
- - 'lib/rgen/core_components/configuration/setup.rb'
55
- - 'lib/rgen/core_components/register_map/generic_map.rb'
56
- - 'lib/rgen/core_components/register_map/setup.rb'
57
- - 'lib/rgen/core_components/rtl/setup.rb'
58
- - 'lib/rgen/output_base/line.rb'
59
-
60
- # Offense count: 28
61
- # Cop supports --auto-correct.
62
- # Configuration parameters: MultiSpaceAllowedForOperators.
63
- Style/SpaceAroundOperators:
64
- Enabled: false
65
-
66
- # Offense count: 42
67
- # Cop supports --auto-correct.
68
- Style/SpaceBeforeComma:
69
- Exclude:
70
- - 'lib/rgen/builder/list_item_entry.rb'
71
- - 'lib/rgen/builtins/bit_field/type.rb'
72
- - 'lib/rgen/builtins/register_block/apb.rb'
73
- - 'lib/rgen/builtins/register_block/clock_reset.rb'
74
- - 'lib/rgen/builtins/register_block/host_if.rb'
75
- - 'lib/rgen/builtins/register_block/response_mux.rb'
76
- - 'lib/rgen/commands.rb'
77
- - 'lib/rgen/core_extensions/forwardable.rb'
78
- - 'rgen.gemspec'
79
-
80
- # Offense count: 5
81
- # Cop supports --auto-correct.
82
- Style/SpaceInsideBrackets:
83
- Exclude:
84
- - 'lib/rgen/commands.rb'
85
-
86
- # Offense count: 2
87
- # Cop supports --auto-correct.
88
- Style/SpaceInsideParens:
89
- Exclude:
90
- - 'lib/rgen/builder/category.rb'
91
-
data/rggen.gemspec DELETED
@@ -1,46 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'rggen/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = 'rggen'
8
- spec.version = RgGen::VERSION
9
- spec.required_ruby_version = '>= 2.0'
10
- spec.authors = ['Taichi Ishitani']
11
- spec.email = ['taichi730@gmail.com']
12
- spec.homepage = 'https://github.com/taichi-ishitani/rggen'
13
-
14
- spec.summary = 'Code generation tool for control registers in a SoC design.'
15
- spec.description = <<-EOS
16
- RgGen is a code generation tool for SoC designers.
17
- It will automatically generate source code for control registers in a SoC design, e.g. RLT, UVM RAL model, from its register map document.
18
- Also RgGen is customizable so you can build your specific generate tool.
19
- EOS
20
- spec.homepage = ''
21
- spec.license = 'MIT'
22
-
23
- spec.files = `git ls-files -z`.split("\x0").reject { |f|
24
- f =~ %r{^(?:
25
- bin/setup
26
- |spec/.*
27
- |Gemfile
28
- |Rakefile
29
- |.gitignore
30
- |.rspec
31
- |.travis.yml
32
- )$}x
33
- }
34
- spec.bindir = 'bin'
35
- spec.executables = ['rggen']
36
- spec.require_paths = ['lib']
37
-
38
- spec.add_runtime_dependency 'baby_erubis', '>= 2.0'
39
- spec.add_runtime_dependency 'facets' , '>= 3.0'
40
- spec.add_runtime_dependency 'roo' , '>= 2.1.1'
41
- spec.add_runtime_dependency 'spreadsheet', '>= 1.0.3'
42
-
43
- spec.add_development_dependency 'rake' , '~> 10.0'
44
- spec.add_development_dependency 'rspec' , '>= 3.3'
45
- spec.add_development_dependency 'rubocop', '>= 0.35'
46
- end