initial commit
This commit is contained in:
262
src/regs/verilog6502_io_regs.sv
Normal file
262
src/regs/verilog6502_io_regs.sv
Normal file
@@ -0,0 +1,262 @@
|
||||
// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator
|
||||
// https://github.com/SystemRDL/PeakRDL-regblock
|
||||
|
||||
module verilog6502_io_regs (
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
|
||||
taxi_apb_if.slv s_apb,
|
||||
|
||||
output verilog6502_io_regs_pkg::verilog6502_io_regs__out_t hwif_out
|
||||
);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// CPU Bus interface logic
|
||||
//--------------------------------------------------------------------------
|
||||
logic cpuif_req;
|
||||
logic cpuif_req_is_wr;
|
||||
logic [11:0] cpuif_addr;
|
||||
logic [31:0] cpuif_wr_data;
|
||||
logic [31:0] cpuif_wr_biten;
|
||||
logic cpuif_req_stall_wr;
|
||||
logic cpuif_req_stall_rd;
|
||||
|
||||
logic cpuif_rd_ack;
|
||||
logic cpuif_rd_err;
|
||||
logic [31:0] cpuif_rd_data;
|
||||
|
||||
logic cpuif_wr_ack;
|
||||
logic cpuif_wr_err;
|
||||
|
||||
`ifndef SYNTHESIS
|
||||
initial begin
|
||||
assert_bad_addr_width: assert($bits(s_apb.paddr) >= verilog6502_io_regs_pkg::VERILOG6502_IO_REGS_MIN_ADDR_WIDTH)
|
||||
else $error("Interface address width of %0d is too small. Shall be at least %0d bits", $bits(s_apb.paddr), verilog6502_io_regs_pkg::VERILOG6502_IO_REGS_MIN_ADDR_WIDTH);
|
||||
assert_bad_data_width: assert($bits(s_apb.pwdata) == verilog6502_io_regs_pkg::VERILOG6502_IO_REGS_DATA_WIDTH)
|
||||
else $error("Interface data width of %0d is incorrect. Shall be %0d bits", $bits(s_apb.pwdata), verilog6502_io_regs_pkg::VERILOG6502_IO_REGS_DATA_WIDTH);
|
||||
end
|
||||
`endif
|
||||
|
||||
// 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_biten <= '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[11:2], 2'b0};
|
||||
cpuif_wr_data <= s_apb.pwdata;
|
||||
for(int i=0; i<4; i++) begin
|
||||
cpuif_wr_biten[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;
|
||||
|
||||
logic cpuif_req_masked;
|
||||
|
||||
// Read & write latencies are balanced. Stalls not required
|
||||
assign cpuif_req_stall_rd = '0;
|
||||
assign cpuif_req_stall_wr = '0;
|
||||
assign cpuif_req_masked = cpuif_req
|
||||
& !(!cpuif_req_is_wr & cpuif_req_stall_rd)
|
||||
& !(cpuif_req_is_wr & cpuif_req_stall_wr);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Address Decode
|
||||
//--------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
logic core_ctrl;
|
||||
logic reset_brq;
|
||||
} decoded_reg_strb_t;
|
||||
decoded_reg_strb_t decoded_reg_strb;
|
||||
logic decoded_err;
|
||||
logic [11:0] decoded_addr;
|
||||
logic decoded_req;
|
||||
logic decoded_req_is_wr;
|
||||
logic [31:0] decoded_wr_data;
|
||||
logic [31:0] decoded_wr_biten;
|
||||
|
||||
always_comb begin
|
||||
automatic logic is_valid_addr;
|
||||
automatic logic is_valid_rw;
|
||||
is_valid_addr = '1; // No valid address check
|
||||
is_valid_rw = '1; // No valid RW check
|
||||
decoded_reg_strb.core_ctrl = cpuif_req_masked & (cpuif_addr == 12'h0);
|
||||
decoded_reg_strb.reset_brq = cpuif_req_masked & (cpuif_addr == 12'hffc);
|
||||
decoded_err = '0;
|
||||
end
|
||||
|
||||
// Pass down signals to next stage
|
||||
assign decoded_addr = cpuif_addr;
|
||||
assign decoded_req = cpuif_req_masked;
|
||||
assign decoded_req_is_wr = cpuif_req_is_wr;
|
||||
assign decoded_wr_data = cpuif_wr_data;
|
||||
assign decoded_wr_biten = cpuif_wr_biten;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Field logic
|
||||
//--------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
struct {
|
||||
struct {
|
||||
logic next;
|
||||
logic load_next;
|
||||
} reset;
|
||||
} core_ctrl;
|
||||
struct {
|
||||
struct {
|
||||
logic [15:0] next;
|
||||
logic load_next;
|
||||
} reset;
|
||||
struct {
|
||||
logic [15:0] next;
|
||||
logic load_next;
|
||||
} brk;
|
||||
} reset_brq;
|
||||
} field_combo_t;
|
||||
field_combo_t field_combo;
|
||||
|
||||
typedef struct {
|
||||
struct {
|
||||
struct {
|
||||
logic value;
|
||||
} reset;
|
||||
} core_ctrl;
|
||||
struct {
|
||||
struct {
|
||||
logic [15:0] value;
|
||||
} reset;
|
||||
struct {
|
||||
logic [15:0] value;
|
||||
} brk;
|
||||
} reset_brq;
|
||||
} field_storage_t;
|
||||
field_storage_t field_storage;
|
||||
|
||||
// Field: verilog6502_io_regs.core_ctrl.reset
|
||||
always_comb begin
|
||||
automatic logic [0:0] next_c;
|
||||
automatic logic load_next_c;
|
||||
next_c = field_storage.core_ctrl.reset.value;
|
||||
load_next_c = '0;
|
||||
if(decoded_reg_strb.core_ctrl && decoded_req_is_wr) begin // SW write
|
||||
next_c = (field_storage.core_ctrl.reset.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]);
|
||||
load_next_c = '1;
|
||||
end
|
||||
field_combo.core_ctrl.reset.next = next_c;
|
||||
field_combo.core_ctrl.reset.load_next = load_next_c;
|
||||
end
|
||||
always_ff @(posedge clk) begin
|
||||
if(rst) begin
|
||||
field_storage.core_ctrl.reset.value <= 1'h1;
|
||||
end else begin
|
||||
if(field_combo.core_ctrl.reset.load_next) begin
|
||||
field_storage.core_ctrl.reset.value <= field_combo.core_ctrl.reset.next;
|
||||
end
|
||||
end
|
||||
end
|
||||
assign hwif_out.core_ctrl.reset.value = field_storage.core_ctrl.reset.value;
|
||||
// Field: verilog6502_io_regs.reset_brq.reset
|
||||
always_comb begin
|
||||
automatic logic [15:0] next_c;
|
||||
automatic logic load_next_c;
|
||||
next_c = field_storage.reset_brq.reset.value;
|
||||
load_next_c = '0;
|
||||
if(decoded_reg_strb.reset_brq && decoded_req_is_wr) begin // SW write
|
||||
next_c = (field_storage.reset_brq.reset.value & ~decoded_wr_biten[15:0]) | (decoded_wr_data[15:0] & decoded_wr_biten[15:0]);
|
||||
load_next_c = '1;
|
||||
end
|
||||
field_combo.reset_brq.reset.next = next_c;
|
||||
field_combo.reset_brq.reset.load_next = load_next_c;
|
||||
end
|
||||
always_ff @(posedge clk) begin
|
||||
if(rst) begin
|
||||
field_storage.reset_brq.reset.value <= 16'h200;
|
||||
end else begin
|
||||
if(field_combo.reset_brq.reset.load_next) begin
|
||||
field_storage.reset_brq.reset.value <= field_combo.reset_brq.reset.next;
|
||||
end
|
||||
end
|
||||
end
|
||||
assign hwif_out.reset_brq.reset.value = field_storage.reset_brq.reset.value;
|
||||
// Field: verilog6502_io_regs.reset_brq.brk
|
||||
always_comb begin
|
||||
automatic logic [15:0] next_c;
|
||||
automatic logic load_next_c;
|
||||
next_c = field_storage.reset_brq.brk.value;
|
||||
load_next_c = '0;
|
||||
if(decoded_reg_strb.reset_brq && decoded_req_is_wr) begin // SW write
|
||||
next_c = (field_storage.reset_brq.brk.value & ~decoded_wr_biten[31:16]) | (decoded_wr_data[31:16] & decoded_wr_biten[31:16]);
|
||||
load_next_c = '1;
|
||||
end
|
||||
field_combo.reset_brq.brk.next = next_c;
|
||||
field_combo.reset_brq.brk.load_next = load_next_c;
|
||||
end
|
||||
always_ff @(posedge clk) begin
|
||||
if(rst) begin
|
||||
field_storage.reset_brq.brk.value <= 16'h200;
|
||||
end else begin
|
||||
if(field_combo.reset_brq.brk.load_next) begin
|
||||
field_storage.reset_brq.brk.value <= field_combo.reset_brq.brk.next;
|
||||
end
|
||||
end
|
||||
end
|
||||
assign hwif_out.reset_brq.brk.value = field_storage.reset_brq.brk.value;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Write response
|
||||
//--------------------------------------------------------------------------
|
||||
assign cpuif_wr_ack = decoded_req & decoded_req_is_wr;
|
||||
// Writes are always granted with no error response
|
||||
assign cpuif_wr_err = '0;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Readback
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
logic [11:0] rd_mux_addr;
|
||||
assign rd_mux_addr = decoded_addr;
|
||||
|
||||
logic readback_err;
|
||||
logic readback_done;
|
||||
logic [31:0] readback_data;
|
||||
always_comb begin
|
||||
automatic logic [31:0] readback_data_var;
|
||||
readback_data_var = '0;
|
||||
if(rd_mux_addr == 12'h0) begin
|
||||
readback_data_var[0] = field_storage.core_ctrl.reset.value;
|
||||
end
|
||||
if(rd_mux_addr == 12'hffc) begin
|
||||
readback_data_var[15:0] = field_storage.reset_brq.reset.value;
|
||||
readback_data_var[31:16] = field_storage.reset_brq.brk.value;
|
||||
end
|
||||
readback_data = readback_data_var;
|
||||
readback_done = decoded_req & ~decoded_req_is_wr;
|
||||
readback_err = '0;
|
||||
end
|
||||
|
||||
assign cpuif_rd_ack = readback_done;
|
||||
assign cpuif_rd_data = readback_data;
|
||||
assign cpuif_rd_err = readback_err;
|
||||
endmodule
|
||||
Reference in New Issue
Block a user