Skip to content

Instantly share code, notes, and snippets.

@taichi-ishitani
Last active December 1, 2021 03:28
Show Gist options
  • Save taichi-ishitani/d703099a0c8c1ec05b22d96e540000d3 to your computer and use it in GitHub Desktop.
Save taichi-ishitani/d703099a0c8c1ec05b22d96e540000d3 to your computer and use it in GitHub Desktop.
Advent Calendar 2021
interface qiita_bus_if
import qiita_bus_pkg::*;
#(
parameter qiita_bus_config BUS_CONFIG = '0
);
logic scmd_accept;
qiita_bus_command mcmd;
logic [BUS_CONFIG.id_width-1:0] mid;
logic [BUS_CONFIG.address_width-1:0] maddr;
logic [BUS_CONFIG.data_width-1:0] mdata;
logic mresp_accept;
logic sresp;
logic [BUS_CONFIG.id_width-1:0] sid;
logic [BUS_CONFIG.data_width-1:0] sdata;
function automatic logic request_ack();
return (mcmd != QIITA_IDLE) && scmd_accept;
endfunction
function automatic logic write_ack();
return (mcmd == QIITA_WRITE) && scmd_accept;
endfunction
function automatic logic read_ack();
return (mcmd == QIITA_READ) && scmd_accept;
endfunction
function automatic logic response_ack();
return sresp && mresp_accept;
endfunction
function automatic qiita_bus_request get_request();
qiita_bus_request request;
request = '{mcmd: mcmd, mid: mid, maddr: maddr, mdata: mdata};
return request;
endfunction
function automatic void put_request(qiita_bus_request request);
mcmd = request.mcmd;
mid = request.mid;
maddr = request.maddr;
mdata = request.mdata;
endfunction
function automatic qiita_bus_response get_response();
qiita_bus_response response;
response = '{sid: sid, sdata: sdata};
return response;
endfunction
function automatic void put_response(qiita_bus_response response);
sid = response.sid;
sdata = response.sdata;
endfunction
localparam int MCMD_LSB = 0;
localparam int MCMD_WIDTH = $bits(qiita_bus_command);
localparam int MID_LSB = MCMD_LSB + MCMD_WIDTH;
localparam int MID_WIDTH = BUS_CONFIG.id_width;
localparam int MADDR_LSB = MID_LSB + MID_WIDTH;
localparam int MADDR_WIDTH = BUS_CONFIG.address_width;
localparam int MDATA_LSB = MADDR_LSB + MADDR_WIDTH;
localparam int MDATA_WIDTH = BUS_CONFIG.data_width;
localparam int SID_LSB = 0;
localparam int SID_WIDTH = BUS_CONFIG.id_width;
localparam int SDATA_LSB = SID_LSB + SID_WIDTH;
localparam int SDATA_WIDTH = BUS_CONFIG.data_width;
localparam int PACKED_REQUEST_WIDTH = get_packed_request_width(BUS_CONFIG);
localparam int PACKED_RESPONSE_WIDTH = get_packed_response_width(BUS_CONFIG);
function automatic logic [PACKED_REQUEST_WIDTH-1:0] get_packed_request();
logic [PACKED_REQUEST_WIDTH-1:0] request;
request[MCMD_LSB+:MCMD_WIDTH] = mcmd;
request[MID_LSB+:MID_WIDTH] = mid;
request[MADDR_LSB+:MADDR_WIDTH] = maddr;
request[MDATA_LSB+:MDATA_WIDTH] = mdata;
return request;
endfunction
function automatic void put_packed_request(logic [PACKED_REQUEST_WIDTH-1:0] request);
mcmd = qiita_bus_command'(request[MCMD_LSB+:MCMD_WIDTH]);
mid = request[MID_LSB+:MID_WIDTH];
maddr = request[MADDR_LSB+:MADDR_WIDTH];
mdata = request[MDATA_LSB+:MDATA_WIDTH];
endfunction
function automatic logic [PACKED_RESPONSE_WIDTH-1:0] get_packed_response();
logic [PACKED_RESPONSE_WIDTH-1:0] response;
response[SID_LSB+:SID_WIDTH] = sid;
response[SDATA_LSB+:SDATA_WIDTH] = sdata;
return response;
endfunction
function automatic void put_packed_response(logic [PACKED_RESPONSE_WIDTH-1:0] response);
sid = response[SID_LSB+:SID_WIDTH];
sdata = response[SDATA_LSB+:SDATA_WIDTH];
endfunction
modport master (
input scmd_accept,
output mcmd,
output mid,
output maddr,
output mdata,
output mresp_accept,
input sresp,
input sid,
input sdata,
import request_ack,
import write_ack,
import read_ack,
import response_ack,
import put_request,
import get_response,
import put_packed_request,
import get_packed_response
);
modport slave (
output scmd_accept,
input mcmd,
input mid,
input maddr,
input mdata,
input mresp_accept,
output sresp,
output sid,
output sdata,
import request_ack,
import write_ack,
import read_ack,
import response_ack,
import get_request,
import put_response,
import get_packed_request,
import put_packed_response
);
endinterface
package qiita_bus_pkg;
typedef struct packed {
int id_width;
int address_width;
int data_width;
} qiita_bus_config;
typedef enum logic [1:0] {
QIITA_IDLE = 2'b00,
QIITA_WRITE = 2'b01,
QIITA_READ = 2'b11
} qiita_bus_command;
`ifndef QIITA_BUS_MAX_ID_WIDTH
`define QIITA_BUS_MAX_ID_WIDTH 8
`endif
`ifndef QIITA_BUS_MAX_ADDRESS_WIDTH
`define QIITA_BUS_MAX_ADDRESS_WIDTH 32
`endif
`ifndef QIITA_BUS_MAX_DATA_WIDTH
`define QIITA_BUS_MAX_DATA_WIDTH 32
`endif
typedef struct packed {
qiita_bus_command mcmd;
logic [`QIITA_BUS_MAX_ID_WIDTH-1:0] mid;
logic [`QIITA_BUS_MAX_ADDRESS_WIDTH-1:0] maddr;
logic [`QIITA_BUS_MAX_DATA_WIDTH-1:0] mdata;
} qiita_bus_request;
typedef struct packed {
logic [`QIITA_BUS_MAX_ID_WIDTH-1:0] sid;
logic [`QIITA_BUS_MAX_DATA_WIDTH-1:0] sdata;
} qiita_bus_response;
function automatic int get_packed_request_width(qiita_bus_config bus_config);
int width = 0;
width += $bits(qiita_bus_command);
width += bus_config.id_width;
width += bus_config.address_width;
width += bus_config.data_width;
return width;
endfunction
function automatic int get_packed_response_width(qiita_bus_config bus_config);
int width = 0;
width += bus_config.id_width;
width += bus_config.data_width
return width;
endfunction
endpackage
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment