Files
PeakRDL-regblock/hand-coded.sv
2021-06-01 23:13:09 -07:00

224 lines
6.5 KiB
Systemverilog

// Hand-coded demo. Not auto-generated
package top_pkg;
// top.whee[][].y
typedef struct {
logic value;
} top__wheexx__y__out_t;
// top.whee[][]
typedef struct {
top__wheexx__y__out_t y;
} top__wheexx__out_t;
// top.asdf[].aaa[].abc
typedef struct {
logic [14:0] value;
} top__asdfx__aaax__abc__out_t;
// top.asdf[].aaa[].def
typedef struct {
logic [3:0] value;
} top__asdfx__aaax__def__out_t;
// top.asdf[].aaa[]
typedef struct {
top__asdfx__aaax__abc__out_t abc;
top__asdfx__aaax__def__out_t def;
} top__asdfx__aaax__out_t;
// top.asdf[].bbb.abc
typedef struct {
logic value;
} top__asdfx__bbb__abc__out_t;
// top.asdf[].bbb.def
typedef struct {
logic value;
} top__asdfx__bbb__def__out_t;
// top.asdf[].bbb
typedef struct {
top__asdfx__bbb__abc__out_t abc;
top__asdfx__bbb__def__out_t def;
} top__asdfx__bbb__out_t;
// top.asdf[]
typedef struct {
top__asdfx__aaax__out_t aaa[4];
top__asdfx__bbb__out_t bbb;
} top__asdfx__out_t;
// top
typedef struct {
top__wheexx__out_t whee[2][8];
top__asdfx__out_t asdf[20];
} top__out_t;
endpackage
module top #(
// TODO: pipeline parameters
)(
input wire clk,
input wire rst,
apb4_intf.slave s_apb,
output top_pkg::top__out_t hwif_out
);
localparam ADDR_WIDTH = 32;
localparam DATA_WIDTH = 32;
//--------------------------------------------------------------------------
// CPU Bus interface logic
//--------------------------------------------------------------------------
logic cpuif_req;
logic cpuif_req_is_wr;
logic [ADDR_WIDTH-1:0] cpuif_addr;
logic [DATA_WIDTH-1:0] cpuif_wr_data;
logic [DATA_WIDTH-1:0] cpuif_wr_bitstrb;
logic cpuif_rd_ack;
logic [DATA_WIDTH-1:0] cpuif_rd_data;
logic cpuif_rd_err;
logic cpuif_wr_ack;
logic cpuif_wr_err;
begin
// Request
logic is_active;
always_ff @(posedge clk) begin
if(rst) begin
is_active <= '0;
cpuif_req <= '0;
cpuif_req_is_wr <= '0;
cpuif_addr <= '0;
cpuif_wr_data <= '0;
cpuif_wr_bitstrb <= '0;
end else begin
if(~is_active) begin
if(s_apb.psel) begin
is_active <= '1;
cpuif_req <= '1;
cpuif_req_is_wr <= s_apb.pwrite;
cpuif_addr <= s_apb.paddr[ADDR_WIDTH-1:0];
cpuif_wr_data <= s_apb.pwdata;
for(int i=0; i<DATA_WIDTH/8; i++) begin
cpuif_wr_bitstrb[i*8 +: 8] <= {8{s_apb.pstrb[i]}};
end
end
end else begin
cpuif_req <= '0;
if(cpuif_rd_ack || cpuif_wr_ack) begin
is_active <= '0;
end
end
end
end
// Response
assign s_apb.pready = cpuif_rd_ack | cpuif_wr_ack;
assign s_apb.prdata = cpuif_rd_data;
assign s_apb.pslverr = cpuif_rd_err | cpuif_wr_err;
end
//--------------------------------------------------------------------------
// Address Decode
//--------------------------------------------------------------------------
typedef struct {
logic whee[2][8];
struct {
logic aaa[4];
logic bbb;
} asdf[20];
} access_strb_t;
access_strb_t access_strb;
always_comb begin
for(int i0=0; i0<2; i0++) begin
for(int i1=0; i1<8; i1++) begin
access_strb.whee[i0][i1] = cpuif_req & (cpuif_addr == 'h0 + i0*'h20 + i1*'h4);
end
end
for(int i0=0; i0<20; i0++) begin
for(int i1=0; i1<4; i1++) begin
access_strb.asdf[i0].aaa[i1] = cpuif_req & (cpuif_addr == 'h40 + i0*'h14 + i1*'h4);
end
access_strb.asdf[i0].bbb = cpuif_req & (cpuif_addr == 'h50 + i0*'h14);
end
end
// Writes are always posted with no error response
assign cpuif_wr_ack = cpuif_req & cpuif_req_is_wr;
assign cpuif_wr_err = '0;
//--------------------------------------------------------------------------
// Field logic
//--------------------------------------------------------------------------
typedef struct {
struct {
logic y;
} whee[2][8];
struct {
struct {
logic [14:0] abc;
logic [3:0] def;
} aaa[4];
struct {
logic abc;
logic def;
} bbb;
} asdf[20];
} field_storage_t;
field_storage_t field_storage;
// TODO: Field next-state logic, and output port signal assignment (aka output mapping layer)
TODO:
//--------------------------------------------------------------------------
// Readback mux
//--------------------------------------------------------------------------
logic readback_err;
logic [DATA_WIDTH-1:0] readback_data;
always_comb begin
readback_err = '0;
readback_data = '0;
if(cpuif_req & ~cpuif_req_is_wr) begin
readback_err = '1;
for(int i0=0; i0<2; i0++) begin
for(int i1=0; i1<8; i1++) begin
if(cpuif_addr == 'h0 + i0*'h20 + i1*'h4) begin
readback_err = '0;
readback_data[0:0] = field_storage.whee[i0][i1].y;
end
end
end
for(int i0=0; i0<20; i0++) begin
for(int i1=0; i1<4; i1++) begin
if(cpuif_addr == 'h40 + i0*'h14 + i1*'h4) begin
readback_err = '0;
readback_data[16:2] = field_storage.asdf[i0].aaa[i1].abc;
readback_data[4:4] = field_storage.asdf[i0].aaa[i1].def;
end
end
if(cpuif_addr == 'h50 + i0*'h14) begin
readback_err = '0;
readback_data[0:0] = field_storage.asdf[i0].bbb.abc;
readback_data[1:1] = field_storage.asdf[i0].bbb.def;
end
end
end
end
assign cpuif_rd_ack = cpuif_req & ~cpuif_req_is_wr;
assign cpuif_rd_data = readback_data;
assign cpuif_rd_err = readback_err;
endmodule