Skip to content

Commit

Permalink
add external register type
Browse files Browse the repository at this point in the history
  • Loading branch information
taichi-ishitani committed Nov 21, 2024
1 parent 2a363f2 commit 3c462c4
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 0 deletions.
5 changes: 5 additions & 0 deletions lib/rggen/veryl/feature.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ def create_port(direction, attributes, &block)
DataObject.new(:port, attributes, &block)
end

def create_modport(_, attributes, &block)
Modport.new(attributes, &block)
end

def create_param(_, attributes, &block)
DataObject.new(:param, attributes, &block)
end
Expand All @@ -28,6 +32,7 @@ def create_const(_, attributes, &block)

define_entity :input, :create_port, :port, -> { register_block }
define_entity :output, :create_port, :port, -> { register_block }
define_entity :modport, :create_modport, :port, -> { register_block }
define_entity :interface, :create_if_instance, :variable, -> { component }
define_entity :param, :create_param, :parameter, -> { register_block }
define_entity :const, :create_const, :parameter, -> { component }
Expand Down
13 changes: 13 additions & 0 deletions lib/rggen/veryl/register/type/external.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
inst u_register: rggen_external_register #(
ADDRESS_WIDTH: <%= address_width %>,
BUS_WIDTH: <%= bus_width %>,
VALUE_WIDTH: <%= value_width %>,
STROBE_WIDTH: <%= strobe_width %>,
START_ADDRESS: <%= start_address %>,
BYTE_SIZE: <%= byte_size %>
)(
i_clk: <%= register_block.clock %>,
i_rst: <%= register_block.reset %>,
register_if: <%= register_if %>,
bus_if: <%= bus_if %>
);
22 changes: 22 additions & 0 deletions lib/rggen/veryl/register/type/external.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,27 @@

RgGen.define_list_item_feature(:register, :type, :external) do
veryl do
build do
param :strobe_width, {
name: "#{register.name}_strobe_width".upcase,
type: :int, default: configuration.byte_width
}
modport :bus_if, {
name: "#{register.name}_bus_if",
interface_type: 'rggen_bus_if', modport: 'master'
}
end

main_code :register, from_template: true

private

def start_address
hex(register.address_range.begin, address_width)
end

def byte_size
register.total_byte_size
end
end
end
88 changes: 88 additions & 0 deletions spec/rggen/veryl/register/type/external_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# frozen_string_literal: true

RSpec.describe 'register/type/external' do
include_context 'clean-up builder'
include_context 'veryl common'

before(:all) do
RgGen.enable(:global, [:bus_width, :address_width, :enable_wide_register])
RgGen.enable(:register_block, :byte_size)
RgGen.enable(:register, [:name, :type, :offset_address, :size])
RgGen.enable(:register, :type, :external)
RgGen.enable(:bit_field, :name)
RgGen.enable(:register_block, :veryl_top)
RgGen.enable(:register, :veryl_top)
end

def create_registers(&body)
create_veryl(&body).registers
end

it 'パラメータ#strobe_widthを持つ' do
registers = create_registers do
byte_size 256
register { name 'register_0'; offset_address 0x00; type :external; size [1] }
end

expect(registers[0])
.to have_param(
:register_block, :strobe_width,
name: 'REGISTER_0_STROBE_WIDTH', type: :int, default: 4
)
end

it 'modport #bus_ifを持つ' do
registers = create_registers do
byte_size 256
register { name 'register_0'; offset_address 0x00; type :external; size [1] }
end

expect(registers[0])
.to have_modport(
:register_block, :bus_if,
name: 'register_0_bus_if', interface_type: 'rggen_bus_if', modport: 'master'
)
end

describe '#generate_code' do
it 'rggen_exernal_registerをインスタンスするコードを出力する' do
registers = create_registers do
byte_size 256
register { name 'register_0'; offset_address 0x00; type :external; size [1] }
register { name 'register_1'; offset_address 0x80; type :external; size [32] }
end

expect(registers[0]).to generate_code(:register, :top_down, <<~'VERYL')
inst u_register: rggen_external_register #(
ADDRESS_WIDTH: 8,
BUS_WIDTH: 32,
VALUE_WIDTH: 32,
STROBE_WIDTH: REGISTER_0_STROBE_WIDTH,
START_ADDRESS: 8'h00,
BYTE_SIZE: 4
)(
i_clk: i_clk,
i_rst: i_rst,
register_if: register_if[0],
bus_if: register_0_bus_if
);
VERYL

expect(registers[1]).to generate_code(:register, :top_down, <<~'VERYL')
inst u_register: rggen_external_register #(
ADDRESS_WIDTH: 8,
BUS_WIDTH: 32,
VALUE_WIDTH: 32,
STROBE_WIDTH: REGISTER_1_STROBE_WIDTH,
START_ADDRESS: 8'h80,
BYTE_SIZE: 128
)(
i_clk: i_clk,
i_rst: i_rst,
register_if: register_if[1],
bus_if: register_1_bus_if
);
VERYL
end
end
end
12 changes: 12 additions & 0 deletions spec/support/shared_context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ def not_have_port(*args, &body)
not_have_declaration(layer, :port, port.declaration).and not_have_identifier(handler, port.identifier)
end

def have_modport(*args, &body)
layer, handler, attributes =
case args.size
when 3 then args[0..2]
when 2 then [nil, args[0], args[1]]
else [nil, args[0], {}]
end
attributes = { name: handler }.merge(attributes)
modport = RgGen::Veryl::Utility::Modport.new(**attributes, &body)
have_declaration(layer, :port, modport.declaration).and have_identifier(handler, modport.identifier)
end

def have_param(*args, &body)
layer, handler, attributes =
case args.size
Expand Down

0 comments on commit 3c462c4

Please sign in to comment.