Skip to content
This repository has been archived by the owner on Nov 14, 2019. It is now read-only.

Commit

Permalink
Implementing axi4lite support (#120)
Browse files Browse the repository at this point in the history
* implemented axi4lite support again (refs #41 & #117)

* fix #121

* Squashed 'rtl/' changes from 1b37ebc..f569178

f569178 Merge pull request #7 from taichi-ishitani/implementing_axi4lite_bridge
a1b35ab impemented AXI4 Lite bridge

git-subtree-dir: rtl
git-subtree-split: f5691786433f8178eabc1b4046149e83020201c6
  • Loading branch information
taichi-ishitani authored Jan 14, 2019
1 parent ba4037e commit cc3b2e2
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 23 deletions.
1 change: 1 addition & 0 deletions lib/rggen/builtins/register_block/host_ifs/axi4lite.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
rggen_host_if_axi4lite #(
.LOCAL_ADDRESS_WIDTH (<%= local_address_width %>),
.DATA_WIDTH (<%= data_width %>),
.TOTAL_REGISTERS (<%= total_registers %>),
.ACCESS_PRIORITY (<%= access_priority %>)
) u_host_if (
.clk (<%= clock %>),
Expand Down
6 changes: 3 additions & 3 deletions lib/rggen/builtins/register_block/host_ifs/axi4lite.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
rtl do
build do
parameter :register_block, :access_priority,
name: 'ACCESS_PRIORITY',
type: :'rggen_rtl_pkg::rggen_direction',
default: :'rggen_rtl_pkg::RGGEN_WRITE'
name: 'ACCESS_PRIORITY',
data_type: :'rggen_rtl_pkg::rggen_direction',
default: :'rggen_rtl_pkg::RGGEN_WRITE'
interface_port :register_block, :axi4lite_if,
type: :rggen_axi4lite_if,
modport: :slave
Expand Down
6 changes: 3 additions & 3 deletions rtl/rggen_axi4lite_if.sv
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ interface rggen_axi4lite_if #(
logic [ADDRESS_WIDTH-1:0] awaddr;
logic [2:0] awprot;
logic wvalid;
logic wraedy;
logic wready;
logic [DATA_WIDTH-1:0] wdata;
logic [DATA_WIDTH/8-1:0] wstrb;
logic bvalid;
Expand All @@ -28,7 +28,7 @@ interface rggen_axi4lite_if #(
output awaddr,
output awprot,
output wvalid,
input wraedy,
input wready,
output wdata,
output wstrb,
input bvalid,
Expand All @@ -50,7 +50,7 @@ interface rggen_axi4lite_if #(
input awaddr,
input awprot,
input wvalid,
output wraedy,
output wready,
input wdata,
input wstrb,
output bvalid,
Expand Down
157 changes: 152 additions & 5 deletions rtl/rggen_host_if_axi4lite.sv
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,159 @@ module rggen_host_if_axi4lite
#(
parameter int LOCAL_ADDRESS_WIDTH = 16,
parameter int DATA_WIDTH = 32,
parameter int TOTAL_REGISTERS = 1,
parameter rggen_direction ACCESS_PRIORITY = RGGEN_WRITE
)(
input clk,
input rst_n,
rggen_axi4lite_if.slave axi4lite_if,
rggen_bus_if.master bus_if
input logic clk,
input logic rst_n,
rggen_axi4lite_if.slave axi4lite_if,
rggen_register_if.master register_if[TOTAL_REGISTERS]
);
// TODO
typedef enum logic [4:0] {
IDLE = 5'b00001,
WRITE_IN_PROGRESS = 5'b00010,
WAIT_FOR_BREADY = 5'b00100,
READ_IN_PROGRESS = 5'b01000,
WAIT_FOR_RREADY = 5'b10000
} e_state;

rggen_bus_if #(LOCAL_ADDRESS_WIDTH, DATA_WIDTH) bus_if();
e_state state;

//--------------------------------------------------------------
// AXI4 Lite
//--------------------------------------------------------------
logic write_request;
logic valid_write_request;
logic write_request_ack;
logic read_request;
logic valid_read_request;
logic read_request_ack;
logic [DATA_WIDTH-1:0] read_data;
rggen_status status;

assign axi4lite_if.awready = write_request_ack;
assign axi4lite_if.wready = write_request_ack;
assign axi4lite_if.bvalid = state[2];
assign axi4lite_if.bresp = status;
assign axi4lite_if.arready = read_request_ack;
assign axi4lite_if.rvalid = state[4];
assign axi4lite_if.rdata = read_data;
assign axi4lite_if.rresp = status;

assign write_request = (axi4lite_if.awvalid && axi4lite_if.wvalid) ? '1 : '0;
assign read_request = axi4lite_if.arvalid;

generate if (ACCESS_PRIORITY == RGGEN_WRITE) begin
assign valid_write_request = (state[0]) ? write_request : '0;
assign valid_read_request = (state[0] && (!valid_write_request)) ? read_request : '0;
end
else begin
assign valid_write_request = (state[0] && (!valid_read_request)) ? write_request : '0;
assign valid_read_request = (state[0]) ? read_request : '0;
end endgenerate

always_ff @(posedge clk, negedge rst_n) begin
if (!rst_n) begin
write_request_ack <= '0;
read_request_ack <= '0;
end
else begin
write_request_ack <= valid_write_request;
read_request_ack <= valid_read_request;
end
end

always_ff @(posedge clk, negedge rst_n) begin
if (!rst_n) begin
read_data <= '0;
status <= RGGEN_OKAY;
end
else if ((state[1] || state[3]) && bus_if.done) begin
read_data <= bus_if.read_data;
status <= bus_if.status;
end
end

//--------------------------------------------------------------
// Bus IF
//--------------------------------------------------------------
rggen_direction direction;
logic [LOCAL_ADDRESS_WIDTH-1:0] address;
logic [DATA_WIDTH-1:0] write_data;
logic [DATA_WIDTH/8-1:0] write_strobe;

assign bus_if.request = (state[1] || state[3]) ? '1 : '0;
assign bus_if.direction = direction;
assign bus_if.address = address;
assign bus_if.write_data = write_data;
assign bus_if.write_strobe = write_strobe;

always_ff @(posedge clk, negedge rst_n) begin
if (!rst_n) begin
direction <= RGGEN_READ;
address <= '0;
write_data <= '0;
write_strobe <= '0;
end
else if (state[0]) begin
if (valid_write_request) begin
direction <= RGGEN_WRITE;
address <= axi4lite_if.awaddr;
write_data <= axi4lite_if.wdata;
write_strobe <= axi4lite_if.wstrb;
end
else if (valid_read_request) begin
direction <= RGGEN_READ;
address <= axi4lite_if.araddr;
end
end
end

rggen_bus_splitter #(
DATA_WIDTH, TOTAL_REGISTERS
) u_bus_splitter (
clk, rst_n, bus_if, register_if
);

//--------------------------------------------------------------
// State Machine
//--------------------------------------------------------------
always_ff @(posedge clk, negedge rst_n) begin
if (!rst_n) begin
state <= IDLE;
end
else begin
case (state)
IDLE: begin
if (valid_write_request) begin
state <= WRITE_IN_PROGRESS;
end
else if (valid_read_request) begin
state <= READ_IN_PROGRESS;
end
end
WRITE_IN_PROGRESS: begin
if (bus_if.write_done) begin
state <= WAIT_FOR_BREADY;
end
end
WAIT_FOR_BREADY: begin
if (axi4lite_if.bready) begin
state <= IDLE;
end
end
READ_IN_PROGRESS: begin
if (bus_if.read_done) begin
state <= WAIT_FOR_RREADY;
end
end
WAIT_FOR_RREADY: begin
if (axi4lite_if.rready) begin
state <= IDLE;
end
end
endcase
end
end
endmodule
31 changes: 19 additions & 12 deletions spec/rggen/builtins/register_block/host_ifs/axi4lite_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@

before(:all) do
enable :global, [:address_width, :data_width]
enable :register_block, [:name, :byte_size, :clock_reset, :host_if]
enable :register_block, [:name, :byte_size]
enable :register_block, [:host_if, :clock_reset]
enable :register_block, :host_if, :axi4lite
enable :register, [:name, :offset_address, :array, :type]
enable :register, :type, [:indirect, :external]
enable :bit_field, [:name, :bit_assignment, :type, :initial_value, :reference]
enable :bit_field, :type, :rw
end

after(:all) do
Expand Down Expand Up @@ -51,8 +56,17 @@ def configuration(load_data = {})
register_map = create_register_map(
configuration,
"block_0" => [
[nil, nil, "block_0"],
[nil, nil, 256 ]
[nil, nil , "block_0" ],
[nil, nil , 252 ],
[ ],
[ ],
[nil, "register_0", "0x00" , nil , nil , "bit_field_0_0", "[0]" , "rw", 0 , nil],
[nil, nil , nil , nil , nil , "bit_field_0_1", "[31:16]", "rw", 0 , nil],
[nil, "register_1", "0x04" , nil , nil , "bit_field_1_0", "[31:0]" , "rw", 0 , nil],
[nil, "register_2", "0x08-0x0F", "[2]" , nil , "bit_field_2_0", "[31:0]" , "rw", 0 , nil],
[nil, "register_3", "0x10" , "[2,4]", "indirect: bit_field_0_0, bit_field_0_1", "bit_field_3_0", "[31:0]" , "rw", 0 , nil],
[nil, "register_4", "0x14" , nil , :external , nil , nil , nil , nil, nil],
[nil, "register_5", "0x18" , nil , :external , nil , nil , nil , nil, nil]
]
)
@rtl = build_rtl_factory.create(configuration, register_map).register_blocks[0]
Expand All @@ -62,16 +76,8 @@ def configuration(load_data = {})
@rtl
end

let(:data_width) do
32
end

let(:host_address_width) do
16
end

it "読み書きの優先度を決めるパラメータを持つ" do
expect(rtl).to have_parameter(:register_block, :access_priority, name: 'ACCESS_PRIORITY', type: :'rggen_rtl_pkg::rggen_direction', default: :'rggen_rtl_pkg::RGGEN_WRITE')
expect(rtl).to have_parameter(:register_block, :access_priority, name: 'ACCESS_PRIORITY', data_type: :'rggen_rtl_pkg::rggen_direction', default: :'rggen_rtl_pkg::RGGEN_WRITE')
end

it "rggen_axi4lite_ifを入出力ポートに持つ" do
Expand All @@ -84,6 +90,7 @@ def configuration(load_data = {})
rggen_host_if_axi4lite #(
.LOCAL_ADDRESS_WIDTH (8),
.DATA_WIDTH (32),
.TOTAL_REGISTERS (14),
.ACCESS_PRIORITY (ACCESS_PRIORITY)
) u_host_if (
.clk (clk),
Expand Down

0 comments on commit cc3b2e2

Please sign in to comment.