Skip to content

Commit

Permalink
add avalon support
Browse files Browse the repository at this point in the history
  • Loading branch information
taichi-ishitani committed Feb 5, 2025
1 parent 5437f8f commit 187c09b
Show file tree
Hide file tree
Showing 7 changed files with 211 additions and 1 deletion.
1 change: 1 addition & 0 deletions lib/rggen/systemverilog/rtl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
'rtl/register_block/protocol',
'rtl/register_block/protocol/apb',
'rtl/register_block/protocol/axi4lite',
'rtl/register_block/protocol/avalon',
'rtl/register_block/protocol/wishbone',
'rtl/register_block/protocol/native',
'rtl/register_file/sv_rtl_top',
Expand Down
17 changes: 17 additions & 0 deletions lib/rggen/systemverilog/rtl/register_block/protocol/avalon.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
rggen_avalon_adapter #(
.ADDRESS_WIDTH (<%= address_width %>),
.LOCAL_ADDRESS_WIDTH (<%= local_address_width %>),
.BUS_WIDTH (<%= bus_width %>),
.REGISTERS (<%= total_registers %>),
.PRE_DECODE (<%= pre_decode %>),
.BASE_ADDRESS (<%= base_address %>),
.BYTE_SIZE (<%= byte_size %>),
.ERROR_STATUS (<%= error_status %>),
.DEFAULT_READ_DATA (<%= default_read_data %>),
.INSERT_SLICER (<%= insert_slicer %>)
) u_adapter (
.i_clk (<%= clock %>),
.i_rst_n (<%= reset %>),
.avalon_if (<%= avalon_if %>),
.register_if (<%= register_if %>)
);
37 changes: 37 additions & 0 deletions lib/rggen/systemverilog/rtl/register_block/protocol/avalon.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# frozen_string_literal: true

RgGen.define_list_item_feature(:register_block, :protocol, :avalon) do
register_map do
verify(:component) do
error_condition { configuration.address_width > 64 }
message do
'address width over 64 bits is not supported: ' \
"#{configuration.address_width}"
end
position do
configuration.feature(:address_width).position
end
end

verify(:component) do
error_condition { register_block.bus_width > 1024 }
message do
'bus width over 1024 bits is not supported: ' \
"#{register_block.bus_width}"
end
position do
register_block.feature(:bus_width).position
end
end
end

sv_rtl do
build do
interface_port :avalon_if, {
name: 'avalon_if', interface_type: 'rggen_avalon_if', modport: 'agent'
}
end

main_code :register_block, from_template: true
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ rggen_native_adapter #(
.PRE_DECODE (<%= pre_decode %>),
.BASE_ADDRESS (<%= base_address %>),
.BYTE_SIZE (<%= byte_size %>),
.USE_READ_STROBE (<%= use_read_strobe %>),
.ERROR_STATUS (<%= error_status %>),
.DEFAULT_READ_DATA (<%= default_read_data %>),
.INSERT_SLICER (<%= insert_slicer %>)
Expand Down
3 changes: 3 additions & 0 deletions lib/rggen/systemverilog/rtl/register_block/protocol/native.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
parameter :strobe_width, {
name: 'STROBE_WIDTH', data_type: :int, default: bus_width / 8
}
parameter :use_read_strobe, {
name: 'USE_READ_STROBE', data_type: :bit, default: 0
}
interface_port :csrbus_if, {
name: 'csrbus_if', interface_type: 'rggen_bus_if', modport: 'slave'
}
Expand Down
145 changes: 145 additions & 0 deletions spec/rggen/systemverilog/rtl/register_block/protocol/avalon_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#! frozen_string_literal: true

RSpec.describe 'register_block/protocol/avalon' do
include_context 'sv rtl common'
include_context 'clean-up builder'

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

def create_register_block(**config_values, &)
configuration = create_configuration(**config_values)
register_map = create_register_map(configuration) do
register_block do
name 'block'
byte_size 256
block_given? && instance_eval(&)
end
end
register_map.register_blocks.first
end

specify 'プロトコル名は:avalon' do
configuration = create_configuration(protocol: :avalon)
expect(configuration).to have_property(:protocol, :avalon)

register_block = create_register_block { protocol :avalon }
expect(register_block).to have_property(:protocol, :avalon)
end

describe 'エラーチェック' do
context 'アドレス幅が64ビットを超える場合' do
it 'SourceErrorを起こす' do
[8, 16, 32, 64].each do |width|
expect {
create_register_block(address_width: width, protocol: :avalon)
}.not_to raise_error

expect {
create_register_block(address_width: width) { protocol :avalon }
}.not_to raise_error
end

[65, 128, 256].each do |width|
message = "address width over 64 bits is not supported: #{width}"

expect {
create_register_block(address_width: width, protocol: :avalon)
}.to raise_source_error message

expect {
create_register_block(address_width: width) { protocol :avalon }
}.to raise_source_error message
end
end

context 'バス幅が1024ビットを超える場合' do
it 'SourceErrorを起こす' do
[8, 16, 32, 64, 128, 256, 512, 1024].each do |width|
expect {
create_register_block(bus_width: width, protocol: :avalon)
}.not_to raise_error

expect {
create_register_block(bus_width: 32) { bus_width width; protocol :avalon }
}.not_to raise_error
end

[2048, 4096].each do |width|
message = "bus width over 1024 bits is not supported: #{width}"

expect {
create_register_block(bus_width: width, protocol: :avalon)
}.to raise_source_error message

expect {
create_register_block(bus_width: 32) { bus_width width; protocol :avalon }
}.to raise_source_error message
end
end
end
end
end

describe 'sv rtl' do
let(:address_width) do
16
end

let(:bus_width) do
32
end

let(:register_block) do
configuration =
create_configuration(
address_width:, bus_width:, protocol: :avalon
)
sv_rtl = create_sv_rtl(configuration) do
name 'block_0'
byte_size 256
register { name 'register_0'; offset_address 0x00; size [1]; type :external }
register { name 'register_1'; offset_address 0x10; size [1]; type :external }
register { name 'register_2'; offset_address 0x20; size [1]; type :external }
end
sv_rtl.register_blocks.first
end

it 'インターフェースポート#avalon_ifを持つ' do
expect(register_block).to have_interface_port(
:avalon_if,
name: 'avalon_if', interface_type: 'rggen_avalon_if', modport: 'agent'
)
end

describe '#generate_code' do
it 'rggen_avalon_adapterをインスタンスするコードを生成する' do
expect(register_block).to generate_code(:register_block, :top_down, <<~'CODE')
rggen_avalon_adapter #(
.ADDRESS_WIDTH (ADDRESS_WIDTH),
.LOCAL_ADDRESS_WIDTH (8),
.BUS_WIDTH (32),
.REGISTERS (3),
.PRE_DECODE (PRE_DECODE),
.BASE_ADDRESS (BASE_ADDRESS),
.BYTE_SIZE (256),
.ERROR_STATUS (ERROR_STATUS),
.DEFAULT_READ_DATA (DEFAULT_READ_DATA),
.INSERT_SLICER (INSERT_SLICER)
) u_adapter (
.i_clk (i_clk),
.i_rst_n (i_rst_n),
.avalon_if (avalon_if),
.register_if (register_if)
);
CODE
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,17 @@ def create_register_block(**config_values, &)
sv_rtl.register_blocks.first
end

it 'パラメータ#strobe_widthを持つ' do
it 'パラメータ#strobe_width/#use_read_strobeを持つ' do
expect(register_block).to have_parameter(
:strobe_width,
name: 'STROBE_WIDTH', parameter_type: :parameter,
data_type: :int, default: bus_width / 8
)
expect(register_block).to have_parameter(
:use_read_strobe,
name: 'USE_READ_STROBE', parameter_type: :parameter,
data_type: :bit, default: 0
)
end

it 'インターフェースポート#csrbus_ifを持つ' do
Expand All @@ -84,6 +89,7 @@ def create_register_block(**config_values, &)
.PRE_DECODE (PRE_DECODE),
.BASE_ADDRESS (BASE_ADDRESS),
.BYTE_SIZE (256),
.USE_READ_STROBE (USE_READ_STROBE),
.ERROR_STATUS (ERROR_STATUS),
.DEFAULT_READ_DATA (DEFAULT_READ_DATA),
.INSERT_SLICER (INSERT_SLICER)
Expand Down

0 comments on commit 187c09b

Please sign in to comment.