Merge pull request #19 from Manarabdelaty/rm_xbar
Removed cross bar switch port
diff --git a/verilog/dv/caravel/defs.h b/verilog/dv/caravel/defs.h
index 96630f1..abfcd44 100644
--- a/verilog/dv/caravel/defs.h
+++ b/verilog/dv/caravel/defs.h
@@ -106,9 +106,11 @@
#define reg_spimaster_data (*(volatile uint32_t*)0x24000004)
// System Area (0x2F00_0000)
-#define reg_pll_out_dest (*(volatile uint32_t*)0x2F00000c)
-#define reg_trap_out_dest (*(volatile uint32_t*)0x2F000010)
-#define reg_irq7_source (*(volatile uint32_t*)0x2F000014)
+#define reg_clk1_out_dest (*(volatile uint32_t*)0x2F000000)
+#define reg_clk2_out_dest (*(volatile uint32_t*)0x2F000004)
+#define reg_trap_out_dest (*(volatile uint32_t*)0x2F000008)
+#define reg_irq7_source (*(volatile uint32_t*)0x2F00000C)
+#define reg_irq8_source (*(volatile uint32_t*)0x2F000010)
// Crossbar Slave Addresses (0x8000_0000 - 0xB000_0000)
#define qspi_ctrl_slave (*(volatile uint32_t*)0x80000000)
diff --git a/verilog/dv/wb_utests/sysctrl_wb/sysctrl_wb_tb.v b/verilog/dv/wb_utests/sysctrl_wb/sysctrl_wb_tb.v
index b4fc6a5..0086016 100644
--- a/verilog/dv/wb_utests/sysctrl_wb/sysctrl_wb_tb.v
+++ b/verilog/dv/wb_utests/sysctrl_wb/sysctrl_wb_tb.v
@@ -46,13 +46,17 @@
integer i;
// System Control Default Register Addresses
- wire [31:0] pll_out_adr = uut.BASE_ADR | uut.PLL_OUT;
+ wire [31:0] clk1_out_adr = uut.BASE_ADR | uut.CLK1_OUT;
+ wire [31:0] clk2_out_adr = uut.BASE_ADR | uut.CLK2_OUT;
wire [31:0] trap_out_adr = uut.BASE_ADR | uut.TRAP_OUT;
wire [31:0] irq7_src_adr = uut.BASE_ADR | uut.IRQ7_SRC;
+ wire [31:0] irq8_src_adr = uut.BASE_ADR | uut.IRQ8_SRC;
- reg pll_output_dest;
+ reg clk1_output_dest;
+ reg clk2_output_dest;
reg trap_output_dest;
reg irq_7_inputsrc;
+ reg irq_8_inputsrc;
initial begin
// Reset Operation
@@ -61,18 +65,28 @@
wb_rst_i = 0;
#2;
- pll_output_dest = 1'b1;
+ clk1_output_dest = 1'b1;
+ clk2_output_dest = 1'b1;
trap_output_dest = 1'b1;
irq_7_inputsrc = 1'b1;
+ irq_8_inputsrc = 1'b1;
// Write to System Control Registers
- write(pll_out_adr, pll_output_dest);
+ write(clk1_out_adr, clk1_output_dest);
+ write(clk2_out_adr, clk2_output_dest);
write(trap_out_adr, trap_output_dest);
write(irq7_src_adr, irq_7_inputsrc);
+ write(irq8_src_adr, irq_8_inputsrc);
#2;
- read(pll_out_adr);
- if (wb_dat_o !== pll_output_dest) begin
- $display("Error reading PLL output destination register.");
+ read(clk1_out_adr);
+ if (wb_dat_o !== clk1_output_dest) begin
+ $display("Error reading CLK1 output destination register.");
+ $finish;
+ end
+
+ read(clk2_out_adr);
+ if (wb_dat_o !== clk2_output_dest) begin
+ $display("Error reading CLK2 output destination register.");
$finish;
end
@@ -88,6 +102,12 @@
$finish;
end
+ read(irq8_src_adr);
+ if (wb_dat_o !== irq_8_inputsrc) begin
+ $display("Error reading IRQ8 input source register.");
+ $finish;
+ end
+
$display("Success!");
$finish;
end
diff --git a/verilog/rtl/caravel.v b/verilog/rtl/caravel.v
index 23f4291..b42eedf 100644
--- a/verilog/rtl/caravel.v
+++ b/verilog/rtl/caravel.v
@@ -344,6 +344,8 @@
.la_output(la_output_core),
.la_oen(la_oen),
// User Project IO Control
+ .mprj_pwrgood(mprj_pwrgood),
+ .mprj2_pwrgood(mprj2_pwrgood),
.mprj_io_loader_resetn(mprj_io_loader_resetn),
.mprj_io_loader_clock(mprj_io_loader_clock),
.mprj_io_loader_data(mprj_io_loader_data),
@@ -380,6 +382,8 @@
wire [3:0] mprj_sel_o_user;
wire [31:0] mprj_adr_o_user;
wire [31:0] mprj_dat_o_user;
+ wire mprj_pwrgood;
+ wire mprj2_pwrgood;
mgmt_protect mgmt_buffers (
.vccd(vccd),
@@ -408,7 +412,9 @@
.mprj_sel_o_user(mprj_sel_o_user),
.mprj_adr_o_user(mprj_adr_o_user),
.mprj_dat_o_user(mprj_dat_o_user),
- .la_data_in_mprj(la_data_in_mprj)
+ .la_data_in_mprj(la_data_in_mprj),
+ .user1_powergood(mprj_pwrgood),
+ .user2_powergood(mprj2_pwrgood)
);
diff --git a/verilog/rtl/counter_timer.v b/verilog/rtl/counter_timer.v
index 9e25281..f569182 100755
--- a/verilog/rtl/counter_timer.v
+++ b/verilog/rtl/counter_timer.v
@@ -8,6 +8,7 @@
) (
input wb_clk_i,
input wb_rst_i,
+ input strobe_in,
input [31:0] wb_adr_i,
input [31:0] wb_dat_i,
input [3:0] wb_sel_i,
@@ -17,6 +18,7 @@
output wb_ack_o,
output [31:0] wb_dat_o,
+ output strobe_out,
output irq
);
wire [31:0] counter_timer_reg_cfg_do;
@@ -48,6 +50,7 @@
counter_timer counter_timer_inst (
.resetn(resetn),
.clkin(wb_clk_i),
+ .strobe_in(strobe_in),
.reg_val_we(reg_val_we),
.reg_val_di(mem_wdata),
.reg_val_do(counter_timer_reg_val_do),
@@ -57,6 +60,7 @@
.reg_dat_we(reg_dat_we),
.reg_dat_di(mem_wdata),
.reg_dat_do(counter_timer_reg_dat_do),
+ .strobe_out(strobe_out),
.irq_out(irq)
);
@@ -65,6 +69,7 @@
module counter_timer (
input resetn,
input clkin,
+ input strobe_in,
input [3:0] reg_val_we,
input [31:0] reg_val_di,
@@ -77,22 +82,25 @@
input [3:0] reg_dat_we,
input [31:0] reg_dat_di,
output [31:0] reg_dat_do,
+ output strobe_out,
output irq_out
);
reg [31:0] value_cur;
reg [31:0] value_reset;
-reg irq_out;
+reg strobe_out;
+wire irq_out;
reg enable; // Enable (start) the counter/timer
reg lastenable; // Previous state of enable (catch rising/falling edge)
reg oneshot; // Set oneshot (1) mode or continuous (0) mode
reg updown; // Count up (1) or down (0)
reg irq_ena; // Enable interrupt on timeout
+reg chain; // Chain to a secondary timer
// Configuration register
-assign reg_cfg_do = {28'd0, irq_ena, updown, oneshot, enable};
+assign reg_cfg_do = {27'd0, irq_ena, chain, updown, oneshot, enable};
always @(posedge clkin or negedge resetn) begin
if (resetn == 1'b0) begin
@@ -100,6 +108,7 @@
lastenable <= 1'b0;
oneshot <= 1'b0;
updown <= 1'b0;
+ chain <= 1'b0;
irq_ena <= 1'b0;
end else begin
lastenable <= enable;
@@ -107,7 +116,8 @@
enable <= reg_cfg_di[0];
oneshot <= reg_cfg_di[1];
updown <= reg_cfg_di[2];
- irq_ena <= reg_cfg_di[3];
+ chain <= reg_cfg_di[3];
+ irq_ena <= reg_cfg_di[4];
end
end
end
@@ -131,10 +141,12 @@
// Counter/timer current value register and timer implementation
+assign irq_out = (irq_ena) ? strobe_out : 1'b0;
+
always @(posedge clkin or negedge resetn) begin
if (resetn == 1'b0) begin
value_cur <= 32'd0;
- irq_out <= 1'b0;
+ strobe_out <= 1'b0;
end else begin
if (reg_dat_we != 4'b0000) begin
if (reg_dat_we[3] == 1'b1) value_cur[31:24] <= reg_dat_di[31:24];
@@ -149,10 +161,12 @@
if (oneshot != 1'b1) begin
value_cur <= 32'd0;
end
- irq_out <= irq_ena;
+ strobe_out <= 1'b1;
end else begin
- value_cur <= value_cur + 1; // count up
- irq_out <= 1'b0;
+ if ((chain == 1'b0) || ((chain == 1'b1) && (strobe_in == 1'b1))) begin
+ value_cur <= value_cur + 1; // count up
+ strobe_out <= 1'b0;
+ end
end
end else begin
if (lastenable == 1'b0) begin
@@ -161,14 +175,16 @@
if (oneshot != 1'b1) begin
value_cur <= value_reset;
end
- irq_out <= irq_ena;
+ strobe_out <= 1'b1;
end else begin
- value_cur <= value_cur - 1; // count down
- irq_out <= 1'b0;
+ if ((chain == 1'b0) || ((chain == 1'b1) && (strobe_in == 1'b1))) begin
+ value_cur <= value_cur - 1; // count down
+ strobe_out <= 1'b0;
+ end
end
end
end else begin
- irq_out <= 1'b0;
+ strobe_out <= 1'b0;
end
end
end
diff --git a/verilog/rtl/mgmt_core.v b/verilog/rtl/mgmt_core.v
index 58d6334..cd8a232 100644
--- a/verilog/rtl/mgmt_core.v
+++ b/verilog/rtl/mgmt_core.v
@@ -45,6 +45,8 @@
// User Project Control Signals
input [MPRJ_IO_PADS-1:0] mgmt_in_data,
output [MPRJ_IO_PADS-1:0] mgmt_out_data,
+ input mprj_pwrgood,
+ input mprj2_pwrgood,
output mprj_io_loader_resetn,
output mprj_io_loader_clock,
output mprj_io_loader_data,
@@ -114,6 +116,11 @@
// flash_sck = mgmt_out_data[9] (output) (user area flash)
// flash_io0 = mgmt_in/out_data[10] (input) (user area flash)
// flash_io1 = mgmt_in/out_data[11] (output) (user area flash)
+ // irq2_pin = mgmt_in_data[12] (input)
+ // trap_mon = mgmt_in_data[13] (output)
+ // clk1_mon = mgmt_in_data[14] (output)
+ // clk2_mon = mgmt_in_data[15] (output)
+
// OEB lines for [0] and [1] are the only ones connected directly to
// the pad. All others have OEB controlled by the configuration bit
@@ -170,11 +177,15 @@
.pass_thru_mgmt_sdo(pass_thru_mgmt_sdo),
// SPI master->slave direct connection
.hk_connect(hk_connect),
+ // Secondary clock (for monitoring)
+ .user_clk(user_clk),
// Logic Analyzer
.la_input(la_input),
.la_output(la_output),
.la_oen(la_oen),
// User Project I/O Configuration
+ .mprj_pwrgood(mprj_pwrgood),
+ .mprj2_pwrgood(mprj2_pwrgood),
.mprj_io_loader_resetn(mprj_io_loader_resetn),
.mprj_io_loader_clock(mprj_io_loader_clock),
.mprj_io_loader_data(mprj_io_loader_data),
diff --git a/verilog/rtl/mgmt_protect.v b/verilog/rtl/mgmt_protect.v
index 8865ee4..df32f81 100644
--- a/verilog/rtl/mgmt_protect.v
+++ b/verilog/rtl/mgmt_protect.v
@@ -18,6 +18,8 @@
inout vssd,
inout vccd1,
inout vssd1,
+ inout vccd2,
+ inout vssd2,
input caravel_clk,
input caravel_clk2,
@@ -40,12 +42,17 @@
output [3:0] mprj_sel_o_user,
output [31:0] mprj_adr_o_user,
output [31:0] mprj_dat_o_user,
- output [127:0] la_data_in_mprj
+ output [127:0] la_data_in_mprj,
+ output user1_powergood,
+ output user2_powergood
);
- wire [73:0] mprj_logic1;
+ wire [74:0] mprj_logic1;
+ wire mprj2_logic1;
+ wire user1_powergood;
+ wire user2_powergood;
- sky130_fd_sc_hd__conb_1 mprj_logic_high [73:0] (
+ sky130_fd_sc_hd__conb_1 mprj_logic_high [74:0] (
.VPWR(vccd1),
.VGND(vssd1),
.VPB(vccd1),
@@ -54,6 +61,16 @@
.LO()
);
+ sky130_fd_sc_hd__conb_1 mprj2_logic_high (
+ .VPWR(vccd2),
+ .VGND(vssd2),
+ .VPB(vccd2),
+ .VNB(vssd2),
+ .HI(mprj2_logic1),
+ .LO()
+ );
+
+
sky130_fd_sc_hd__einvp_8 mprj_rstn_buf (
.VPWR(vccd),
.VGND(vssd),
@@ -160,4 +177,26 @@
.TE(~la_oen)
);
+ /* The conb cell output is a resistive connection directly to */
+ /* the power supply, so when returning the user1_powergood */
+ /* signal, make sure that it is buffered properly. */
+
+ sky130_fd_sc_hd__buf_8 mprj_pwrgood (
+ .VPWR(vccd),
+ .VGND(vssd),
+ .VPB(vccd),
+ .VNB(vssd),
+ .A(mprj_logic1[74]),
+ .X(user1_powergood)
+ );
+
+ sky130_fd_sc_hd__buf_8 mprj2_pwrgood (
+ .VPWR(vccd),
+ .VGND(vssd),
+ .VPB(vccd),
+ .VNB(vssd),
+ .A(mprj_logic2),
+ .X(user2_powergood)
+ );
+
endmodule
diff --git a/verilog/rtl/mgmt_soc.v b/verilog/rtl/mgmt_soc.v
index 4ec9158..8d7dc71 100644
--- a/verilog/rtl/mgmt_soc.v
+++ b/verilog/rtl/mgmt_soc.v
@@ -70,6 +70,8 @@
output [127:0] la_oen, // LA output enable (active low)
// User Project I/O Configuration (serial load)
+ input mprj_pwrgood,
+ input mprj2_pwrgood,
output mprj_io_loader_resetn,
output mprj_io_loader_clock,
output mprj_io_loader_data,
@@ -120,6 +122,8 @@
// SPI master->slave direct link
output hk_connect,
+ // User clock monitoring
+ input user_clk,
// WB MI A (User project)
input mprj_ack_i,
@@ -186,9 +190,10 @@
parameter LA_ENA_3 = 8'h1c;
// System Control Registers
- parameter PLL_OUT = 8'h00;
- parameter TRAP_OUT = 8'h04;
- parameter IRQ7_SRC = 8'h08;
+ parameter PWRGOOD = 8'h00;
+ parameter CLK_OUT = 8'h04;
+ parameter TRAP_OUT = 8'h08;
+ parameter IRQ_SRC = 8'h0c;
// Wishbone Interconnect
localparam ADR_WIDTH = 32;
@@ -241,6 +246,10 @@
// flash_sck = mgmt_out_data[9] (output) (user area flash)
// flash_io0 = mgmt_in/out_data[10] (input) (user area flash)
// flash_io1 = mgmt_in/out_data[11] (output) (user area flash)
+ // irq2_pin = mgmt_in_data[12] (input)
+ // trap_mon = mgmt_in_data[13] (output)
+ // clk1_mon = mgmt_in_data[14] (output)
+ // clk2_mon = mgmt_in_data[15] (output)
// OEB lines for [0] and [1] are the only ones connected directly to
// the pad. All others have OEB controlled by the configuration bit
@@ -252,20 +261,11 @@
wire gpio_outenb; // Intermediate GPIO out enable (bar)
wire gpio_out; // Intermediate GPIO output
- wire gpio; // GPIO output data
- wire gpio_pu; // GPIO pull-up enable
- wire gpio_pd; // GPIO pull-down enable
- wire gpio_oeb; // GPIO output enable (sense negative)
-
- wire pll_output_dest; // PLL clock output destination
wire trap_output_dest; // Trap signal output destination
+ wire clk1_output_dest; // Core clock1 signal output destination
+ wire clk2_output_dest; // Core clock2 signal output destination
wire irq_7_inputsrc; // IRQ 7 source
-
- // GPIO assignments
- assign gpio_out = (trap_output_dest == 1'b1) ? trap : gpio;
- assign gpio_outenb = (trap_output_dest == 1'b0) ? gpio_oeb : 1'b0;
- assign gpio_pullup = (trap_output_dest == 1'b0) ? gpio_pu : 1'b0;
- assign gpio_pulldown = (trap_output_dest == 1'b0) ? gpio_pd : 1'b0;
+ wire irq_8_inputsrc; // IRQ 8 source
// Convert GPIO signals to sky130_fd_io pad signals
convert_gpio_sigs convert_gpio_bit (
@@ -282,6 +282,7 @@
reg [31:0] irq;
wire irq_7;
+ wire irq_8;
wire irq_stall;
wire irq_uart;
wire irq_spi_master;
@@ -290,6 +291,7 @@
assign irq_stall = 0;
assign irq_7 = (irq_7_inputsrc == 1'b1) ? mgmt_in_data[7] : 1'b0;
+ assign irq_8 = (irq_8_inputsrc == 1'b1) ? mgmt_in_data[12] : 1'b0;
always @* begin
irq = 0;
@@ -472,6 +474,8 @@
.irq(irq_spi_master)
);
+ wire strobe_counter_timer0, strobe_counter_timer1;
+
// Wishbone Counter-timer 0
wire counter_timer0_stb_i;
wire counter_timer0_ack_o;
@@ -486,6 +490,7 @@
// Wishbone Interface
.wb_clk_i(wb_clk_i),
.wb_rst_i(wb_rst_i),
+ .strobe_in(strobe_counter_timer1),
.wb_adr_i(cpu_adr_o),
.wb_dat_i(cpu_dat_o),
@@ -496,6 +501,7 @@
.wb_stb_i(counter_timer0_stb_i),
.wb_ack_o(counter_timer0_ack_o),
.wb_dat_o(counter_timer0_dat_o),
+ .strobe_out(strobe_counter_timer0),
.irq(irq_counter_timer0)
);
@@ -513,6 +519,7 @@
// Wishbone Interface
.wb_clk_i(wb_clk_i),
.wb_rst_i(wb_rst_i),
+ .strobe_in(strobe_counter_timer0),
.wb_adr_i(cpu_adr_o),
.wb_dat_i(cpu_dat_o),
@@ -523,6 +530,7 @@
.wb_stb_i(counter_timer1_stb_i),
.wb_ack_o(counter_timer1_ack_o),
.wb_dat_o(counter_timer1_dat_o),
+ .strobe_out(strobe_counter_timer1),
.irq(irq_counter_timer1)
);
@@ -549,10 +557,10 @@
.wb_ack_o(gpio_ack_o),
.wb_dat_o(gpio_dat_o),
.gpio_in_pad(gpio_in_pad),
- .gpio(gpio),
- .gpio_oeb(gpio_oeb),
- .gpio_pu(gpio_pu),
- .gpio_pd(gpio_pd)
+ .gpio(gpio_out),
+ .gpio_oeb(gpio_outenb),
+ .gpio_pu(gpio_pullup),
+ .gpio_pd(gpio_pulldown)
);
// Wishbone Slave System Control Register
@@ -562,9 +570,10 @@
sysctrl_wb #(
.BASE_ADR(SYS_BASE_ADR),
- .PLL_OUT(PLL_OUT),
+ .PWRGOOD(PWRGOOD),
+ .CLK_OUT(CLK_OUT),
.TRAP_OUT(TRAP_OUT),
- .IRQ7_SRC(IRQ7_SRC)
+ .IRQ_SRC(IRQ_SRC)
) sysctrl (
.wb_clk_i(wb_clk_i),
.wb_rst_i(wb_rst_i),
@@ -579,9 +588,13 @@
.wb_ack_o(sys_ack_o),
.wb_dat_o(sys_dat_o),
- .pll_output_dest(pll_output_dest),
+ .usr1_pwrgood(mprj_pwrgood),
+ .usr2_pwrgood(mprj2_pwrgood),
.trap_output_dest(trap_output_dest),
- .irq_7_inputsrc(irq_7_inputsrc)
+ .clk1_output_dest(clk1_output_dest),
+ .clk2_output_dest(clk2_output_dest),
+ .irq_7_inputsrc(irq_7_inputsrc),
+ .irq_8_inputsrc(irq_8_inputsrc)
);
// Logic Analyzer
@@ -627,7 +640,14 @@
// mprj GPIO-as-output from applying data when that function
// is active
- assign mgmt_out_data[MPRJ_IO_PADS-1:7] = mgmt_out_pre[MPRJ_IO_PADS-1:7];
+ assign mgmt_out_data[MPRJ_IO_PADS-1:16] = mgmt_out_pre[MPRJ_IO_PADS-1:16];
+
+ // Routing of output monitors (PLL, trap, clk1, clk2)
+ assign mgmt_out_data[15] = clk2_output_dest ? user_clk : mgmt_out_pre[15];
+ assign mgmt_out_data[14] = clk1_output_dest ? clk : mgmt_out_pre[14];
+ assign mgmt_out_data[13] = trap_output_dest ? trap : mgmt_out_pre[13];
+
+ assign mgmt_out_data[12:7] = mgmt_out_pre[12:7];
assign mgmt_out_data[6] = uart_enabled ? ser_tx : mgmt_out_pre[6];
assign mgmt_out_data[5:0] = mgmt_out_pre[5:0];
diff --git a/verilog/rtl/sysctrl.v b/verilog/rtl/sysctrl.v
index 86ec1e5..acdb045 100644
--- a/verilog/rtl/sysctrl.v
+++ b/verilog/rtl/sysctrl.v
@@ -1,8 +1,9 @@
module sysctrl_wb #(
- parameter BASE_ADR = 32'h2F00_0000,
- parameter PLL_OUT = 8'h00,
- parameter TRAP_OUT = 8'h04,
- parameter IRQ7_SRC = 8'h08
+ parameter BASE_ADR = 32'h2F00_0000,
+ parameter PWRGOOD = 8'h00,
+ parameter CLK_OUT = 8'h04,
+ parameter TRAP_OUT = 8'h08,
+ parameter IRQ_SRC = 8'h0c
) (
input wb_clk_i,
input wb_rst_i,
@@ -17,9 +18,13 @@
output [31:0] wb_dat_o,
output wb_ack_o,
- output pll_output_dest,
+ input usr1_pwrgood,
+ input usr2_pwrgood,
+ output clk1_output_dest,
+ output clk2_output_dest,
output trap_output_dest,
- output irq_7_inputsrc
+ output irq_7_inputsrc,
+ output irq_8_inputsrc
);
@@ -36,9 +41,10 @@
sysctrl #(
.BASE_ADR(BASE_ADR),
- .PLL_OUT(PLL_OUT),
+ .PWRGOOD(PWRGOOD),
+ .CLK_OUT(CLK_OUT),
.TRAP_OUT(TRAP_OUT),
- .IRQ7_SRC(IRQ7_SRC)
+ .IRQ_SRC(IRQ_SRC)
) sysctrl (
.clk(wb_clk_i),
.resetn(resetn),
@@ -50,9 +56,12 @@
.iomem_rdata(wb_dat_o),
.iomem_ready(ready),
- .pll_output_dest(pll_output_dest),
+ .usr1_pwrgood(usr1_pwrgood),
+ .usr2_pwrgood(usr2_pwrgood),
+ .clk1_output_dest(clk1_output_dest),
+ .clk2_output_dest(clk2_output_dest),
.trap_output_dest(trap_output_dest),
-
+ .irq_8_inputsrc(irq_8_inputsrc),
.irq_7_inputsrc(irq_7_inputsrc)
);
@@ -60,9 +69,10 @@
module sysctrl #(
parameter BASE_ADR = 32'h2300_0000,
- parameter PLL_OUT = 8'h00,
- parameter TRAP_OUT = 8'h04,
- parameter IRQ7_SRC = 8'h08
+ parameter PWRGOOD = 8'h00,
+ parameter CLK_OUT = 8'h04,
+ parameter TRAP_OUT = 8'h08,
+ parameter IRQ_SRC = 8'h0c
) (
input clk,
input resetn,
@@ -74,45 +84,63 @@
output reg [31:0] iomem_rdata,
output reg iomem_ready,
- output pll_output_dest,
+ input usr1_pwrgood,
+ input usr2_pwrgood,
+ output clk1_output_dest,
+ output clk2_output_dest,
output trap_output_dest,
- output irq_7_inputsrc
+ output irq_7_inputsrc,
+ output irq_8_inputsrc
);
- reg pll_output_dest;
+ reg clk1_output_dest;
+ reg clk2_output_dest;
reg trap_output_dest;
reg irq_7_inputsrc;
+ reg irq_8_inputsrc;
- assign pll_out_sel = (iomem_addr[7:0] == PLL_OUT);
+ wire usr1_pwrgood;
+ wire usr2_pwrgood;
+
+ assign pwrgood_sel = (iomem_addr[7:0] == PWRGOOD);
+ assign clk_out_sel = (iomem_addr[7:0] == CLK_OUT);
assign trap_out_sel = (iomem_addr[7:0] == TRAP_OUT);
-
- assign irq7_sel = (iomem_addr[7:0] == IRQ7_SRC);
+ assign irq_sel = (iomem_addr[7:0] == IRQ_SRC);
always @(posedge clk) begin
if (!resetn) begin
- pll_output_dest <= 0;
+ clk1_output_dest <= 0;
+ clk2_output_dest <= 0;
trap_output_dest <= 0;
irq_7_inputsrc <= 0;
+ irq_8_inputsrc <= 0;
end else begin
iomem_ready <= 0;
if (iomem_valid && !iomem_ready && iomem_addr[31:8] == BASE_ADR[31:8]) begin
iomem_ready <= 1'b 1;
- if (pll_out_sel) begin
- iomem_rdata <= {31'd0, pll_output_dest};
- if (iomem_wstrb[0])
- pll_output_dest <= iomem_wdata[0];
+ if (pwrgood_sel) begin
+ iomem_rdata <= {30'd0, usr2_pwrgood, usr1_pwrgood};
+ // These are read-only bits; no write behavior on wstrb.
+
+ end else if (clk_out_sel) begin
+ iomem_rdata <= {30'd0, clk2_output_dest, clk1_output_dest};
+ if (iomem_wstrb[0]) begin
+ clk1_output_dest <= iomem_wdata[0];
+ clk2_output_dest <= iomem_wdata[1];
+ end
end else if (trap_out_sel) begin
iomem_rdata <= {31'd0, trap_output_dest};
if (iomem_wstrb[0])
trap_output_dest <= iomem_wdata[0];
- end else if (irq7_sel) begin
- iomem_rdata <= {31'd0, irq_7_inputsrc};
- if (iomem_wstrb[0])
+ end else if (irq_sel) begin
+ iomem_rdata <= {30'd0, irq_8_inputsrc, irq_7_inputsrc};
+ if (iomem_wstrb[0]) begin
irq_7_inputsrc <= iomem_wdata[0];
-
+ irq_8_inputsrc <= iomem_wdata[1];
+ end
end
end
end