Line 43... |
Line 43... |
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//
|
//
|
// CVS Revision History
|
// CVS Revision History
|
//
|
//
|
// $Log: not supported by cvs2svn $
|
// $Log: not supported by cvs2svn $
|
|
// Revision 1.2 2001/10/31 02:26:51 lampret
|
|
// Fixed wb_err_o.
|
|
//
|
// Revision 1.1 2001/09/18 18:49:07 lampret
|
// Revision 1.1 2001/09/18 18:49:07 lampret
|
// Changed top level ptc into gpio_top. Changed defines.v into gpio_defines.v.
|
// Changed top level ptc into gpio_top. Changed defines.v into gpio_defines.v.
|
//
|
//
|
// Revision 1.1 2001/08/21 21:39:28 lampret
|
// Revision 1.1 2001/08/21 21:39:28 lampret
|
// Changed directory structure, port names and drfines.
|
// Changed directory structure, port names and drfines.
|
Line 182... |
Line 185... |
wire rgpio_ptrig_sel;// RGPIO_PTRIG select
|
wire rgpio_ptrig_sel;// RGPIO_PTRIG select
|
wire rgpio_aux_sel; // RGPIO_AUX select
|
wire rgpio_aux_sel; // RGPIO_AUX select
|
wire rgpio_ctrl_sel; // RGPIO_CTRL select
|
wire rgpio_ctrl_sel; // RGPIO_CTRL select
|
wire latch_clk; // Latch clock
|
wire latch_clk; // Latch clock
|
wire full_decoding; // Full address decoding qualification
|
wire full_decoding; // Full address decoding qualification
|
reg [dw-1:0] wb_dat_o; // Data out
|
wire [gw-1:0] in_muxed; // Muxed inputs
|
|
wire wb_ack; // WB Acknowledge
|
|
wire wb_err; // WB Error
|
|
wire wb_inta; // WB Interrupt
|
|
reg [dw-1:0] wb_dat; // WB Data out
|
|
`ifdef GPIO_REGISTERED_WB_OUTPUTS
|
|
reg wb_ack_o; // WB Acknowledge
|
|
reg wb_err_o; // WB Error
|
|
reg wb_inta_o; // WB Interrupt
|
|
reg [dw-1:0] wb_dat_o; // WB Data out
|
|
`endif
|
|
wire [gw-1:0] out_pad; // GPIO Outputs
|
|
`ifdef GPIO_REGISTERED_IO_OUTPUTS
|
|
reg [gw-1:0] out_pad_o; // GPIO Outputs
|
|
`endif
|
|
wire [gw-1:0] extc_in; // Muxed inputs sampled by external clock
|
|
wire pext_clk; // External clock for posedge flops
|
|
reg [gw-1:0] pextc_sampled; // Posedge external clock sampled inputs
|
|
`ifdef GPIO_NO_NEGEDGE_FLOPS
|
|
`else
|
|
reg [gw-1:0] nextc_sampled; // Negedge external clock sampled inputs
|
|
`endif
|
|
|
//
|
//
|
// All WISHBONE transfer terminations are successful except when:
|
// All WISHBONE transfer terminations are successful except when:
|
// a) full address decoding is enabled and address doesn't match
|
// a) full address decoding is enabled and address doesn't match
|
// any of the GPIO registers
|
// any of the GPIO registers
|
// b) wb_sel_i evaluation is enabled and one of the wb_sel_i inputs is zero
|
// b) wb_sel_i evaluation is enabled and one of the wb_sel_i inputs is zero
|
//
|
//
|
assign wb_ack_o = wb_cyc_i & wb_stb_i & !wb_err_o;
|
|
|
//
|
|
// WB Acknowledge
|
|
//
|
|
assign wb_ack = wb_cyc_i & wb_stb_i & !wb_err_o;
|
|
|
|
//
|
|
// Optional registration of WB Ack
|
|
//
|
|
`ifdef GPIO_REGISTERED_WB_OUTPUTS
|
|
always @(posedge wb_clk_i or posedge wb_rst_i)
|
|
if (wb_rst_i)
|
|
wb_ack_o <= #1 1'b0;
|
|
else
|
|
wb_ack_o <= #1 wb_ack;
|
|
`else
|
|
assign wb_ack_o = wb_ack;
|
|
`endif
|
|
|
|
//
|
|
// WB Error
|
|
//
|
`ifdef GPIO_FULL_DECODE
|
`ifdef GPIO_FULL_DECODE
|
`ifdef GPIO_STRICT_32BIT_ACCESS
|
`ifdef GPIO_STRICT_32BIT_ACCESS
|
assign wb_err_o = wb_cyc_i & wb_stb_i & (!full_decoding | (wb_sel_i != 4'b1111));
|
assign wb_err = wb_cyc_i & wb_stb_i & (!full_decoding | (wb_sel_i != 4'b1111));
|
`else
|
`else
|
assign wb_err_o = wb_cyc_i & wb_stb_i & !full_decoding;
|
assign wb_err = wb_cyc_i & wb_stb_i & !full_decoding;
|
`endif
|
`endif
|
`else
|
`else
|
`ifdef GPIO_STRICT_32BIT_ACCESS
|
`ifdef GPIO_STRICT_32BIT_ACCESS
|
assign wb_err_o = wb_cyc_i & wb_stb_i & (wb_sel_i != 4'b1111);
|
assign wb_err = wb_cyc_i & wb_stb_i & (wb_sel_i != 4'b1111);
|
`else
|
`else
|
assign wb_err_o = 1'b0;
|
assign wb_err = 1'b0;
|
`endif
|
`endif
|
`endif
|
`endif
|
|
|
//
|
//
|
// Latch clock is selected by RGPIO_CTRL[ECLK]. When it is set,
|
// Optional registration of WB error
|
// external clock is used.
|
|
//
|
//
|
assign latch_clk = rgpio_ctrl[`GPIO_RGPIO_CTRL_ECLK] ?
|
`ifdef GPIO_REGISTERED_WB_OUTPUTS
|
ext_clk_pad_i ^ rgpio_ctrl[`GPIO_RGPIO_CTRL_NEC] : wb_clk_i;
|
always @(posedge wb_clk_i or posedge wb_rst_i)
|
|
if (wb_rst_i)
|
|
wb_err_o <= #1 1'b0;
|
|
else
|
|
wb_err_o <= #1 wb_err;
|
|
`else
|
|
assign wb_err_o = wb_err;
|
|
`endif
|
|
|
//
|
//
|
// Full address decoder
|
// Full address decoder
|
//
|
//
|
`ifdef GPIO_FULL_DECODE
|
`ifdef GPIO_FULL_DECODE
|
Line 258... |
Line 309... |
if (wb_rst_i)
|
if (wb_rst_i)
|
rgpio_out <= #1 {gw{1'b0}};
|
rgpio_out <= #1 {gw{1'b0}};
|
else if (rgpio_out_sel && wb_we_i)
|
else if (rgpio_out_sel && wb_we_i)
|
rgpio_out <= #1 wb_dat_i[gw-1:0];
|
rgpio_out <= #1 wb_dat_i[gw-1:0];
|
`else
|
`else
|
assign rgpio_out = `GPIO_DEF_RPGIO_OUT; // RGPIO_OUT = 0x0
|
assign rgpio_out = `GPIO_DEF_RGPIO_OUT; // RGPIO_OUT = 0x0
|
`endif
|
`endif
|
|
|
//
|
//
|
// Write to RGPIO_OE
|
// Write to RGPIO_OE. Bits in RGPIO_OE are stored inverted.
|
//
|
//
|
`ifdef GPIO_RGPIO_OE
|
`ifdef GPIO_RGPIO_OE
|
always @(posedge wb_clk_i or posedge wb_rst_i)
|
always @(posedge wb_clk_i or posedge wb_rst_i)
|
if (wb_rst_i)
|
if (wb_rst_i)
|
rgpio_oe <= #1 {gw{1'b0}};
|
rgpio_oe <= #1 {gw{1'b0}};
|
else if (rgpio_oe_sel && wb_we_i)
|
else if (rgpio_oe_sel && wb_we_i)
|
rgpio_oe <= #1 wb_dat_i[gw-1:0];
|
rgpio_oe <= #1 ~wb_dat_i[gw-1:0];
|
`else
|
`else
|
assign rgpio_oe = `GPIO_DEF_RPGIO_OE; // RGPIO_OE = 0x0
|
assign rgpio_oe = `GPIO_DEF_RPGIO_OE; // RGPIO_OE = 0x0
|
`endif
|
`endif
|
|
|
//
|
//
|
Line 317... |
Line 368... |
|
|
//
|
//
|
// Latch into RGPIO_IN
|
// Latch into RGPIO_IN
|
//
|
//
|
`ifdef GPIO_RGPIO_IN
|
`ifdef GPIO_RGPIO_IN
|
always @(posedge latch_clk or posedge wb_rst_i)
|
always @(posedge wb_clk_i or posedge wb_rst_i)
|
if (wb_rst_i)
|
if (wb_rst_i)
|
rgpio_in <= #1 {gw{1'b0}};
|
rgpio_in <= #1 {gw{1'b0}};
|
else
|
else
|
rgpio_in <= #1 in_pad_i;
|
rgpio_in <= #1 in_muxed;
|
|
`else
|
|
assign rgpio_in = in_muxed;
|
|
`endif
|
|
|
|
//
|
|
// Mux inputs directly from input pads with inputs sampled by external clock
|
|
//
|
|
assign in_muxed = rgpio_ctrl[`GPIO_RGPIO_CTRL_ECLK] ? extc_in : in_pad_i;
|
|
|
|
//
|
|
// Posedge pext_clk is inverted by NEC bit if negedge flops are not allowed.
|
|
// If negedge flops are allowed, pext_clk only clocks posedge flops.
|
|
//
|
|
`ifdef GPIO_NO_NEGEDGE_FLOPS
|
|
assign pext_clk = rgpio_ctrl[`GPIO_RGPIO_CTRL_NEC] ? ~ext_clk_pad_i : ext_clk_pad_i;
|
|
`else
|
|
assign pext_clk = ext_clk_pad_i;
|
|
`endif
|
|
|
|
//
|
|
// If negedge flops are allowed, ext_in is mux of negedge and posedge external clocked flops.
|
|
//
|
|
`ifdef GPIO_NO_NEGEDGE_FLOPS
|
|
assign extc_in = pextc_sampled;
|
|
`else
|
|
assign extc_in = rgpio_ctrl[`GPIO_RGPIO_CTRL_NEC] ? nextc_sampled : pextc_sampled;
|
|
`endif
|
|
|
|
//
|
|
// Latch using posedge external clock
|
|
//
|
|
always @(posedge pext_clk or posedge wb_rst_i)
|
|
if (wb_rst_i)
|
|
pextc_sampled <= #1 {gw{1'b0}};
|
|
else
|
|
pextc_sampled <= #1 in_pad_i;
|
|
|
|
//
|
|
// Latch using negedge external clock
|
|
//
|
|
`ifdef GPIO_NO_NEGEDGE_FLOPS
|
`else
|
`else
|
assign rgpio_in = in_pad_i;
|
always @(negedge ext_clk_pad_i or posedge wb_rst_i)
|
|
if (wb_rst_i)
|
|
nextc_sampled <= #1 {gw{1'b0}};
|
|
else
|
|
nextc_sampled <= #1 in_pad_i;
|
`endif
|
`endif
|
|
|
//
|
//
|
// Read GPIO registers
|
// Mux all registers when doing a read of GPIO registers
|
//
|
//
|
always @(wb_adr_i or rgpio_in or rgpio_out or rgpio_oe or rgpio_inte or
|
always @(wb_adr_i or rgpio_in or rgpio_out or rgpio_oe or rgpio_inte or
|
rgpio_ptrig or rgpio_aux or rgpio_ctrl)
|
rgpio_ptrig or rgpio_aux or rgpio_ctrl)
|
case (wb_adr_i[`GPIO_OFS_BITS]) // synopsys full_case parallel_case
|
case (wb_adr_i[`GPIO_OFS_BITS]) // synopsys full_case parallel_case
|
`ifdef GPIO_READREGS
|
`ifdef GPIO_READREGS
|
`GPIO_RGPIO_OUT: begin
|
`GPIO_RGPIO_OUT: begin
|
wb_dat_o[dw-1:0] <= {{dw-gw{1'b0}}, rgpio_out};
|
wb_dat[dw-1:0] <= {{dw-gw{1'b0}}, rgpio_out};
|
end
|
end
|
`GPIO_RGPIO_OE: begin
|
`GPIO_RGPIO_OE: begin
|
wb_dat_o[dw-1:0] <= {{dw-gw{1'b0}}, rgpio_oe};
|
wb_dat[dw-1:0] <= {{dw-gw{1'b0}}, ~rgpio_oe};
|
end
|
end
|
`GPIO_RGPIO_INTE: begin
|
`GPIO_RGPIO_INTE: begin
|
wb_dat_o[dw-1:0] <= {{dw-gw{1'b0}}, rgpio_inte};
|
wb_dat[dw-1:0] <= {{dw-gw{1'b0}}, rgpio_inte};
|
end
|
end
|
`GPIO_RGPIO_PTRIG: begin
|
`GPIO_RGPIO_PTRIG: begin
|
wb_dat_o[dw-1:0] <= {{dw-gw{1'b0}}, rgpio_ptrig};
|
wb_dat[dw-1:0] <= {{dw-gw{1'b0}}, rgpio_ptrig};
|
end
|
end
|
`GPIO_RGPIO_AUX: begin
|
`GPIO_RGPIO_AUX: begin
|
wb_dat_o[dw-1:0] <= {{dw-gw{1'b0}}, rgpio_aux};
|
wb_dat[dw-1:0] <= {{dw-gw{1'b0}}, rgpio_aux};
|
end
|
end
|
`GPIO_RGPIO_CTRL: begin
|
`GPIO_RGPIO_CTRL: begin
|
wb_dat_o[3:0] <= rgpio_ctrl;
|
wb_dat[3:0] <= rgpio_ctrl;
|
wb_dat_o[dw-1:4] <= {dw-4{1'b0}};
|
wb_dat[dw-1:4] <= {dw-4{1'b0}};
|
end
|
end
|
`endif
|
`endif
|
default: begin
|
default: begin
|
wb_dat_o[dw-1:0] <= {{dw-gw{1'b0}}, rgpio_in};
|
wb_dat[dw-1:0] <= {{dw-gw{1'b0}}, rgpio_in};
|
end
|
end
|
endcase
|
endcase
|
|
|
//
|
//
|
|
// WB data output
|
|
//
|
|
`ifdef GPIO_REGISTERED_WB_OUTPUTS
|
|
always @(posedge wb_clk_i or posedge wb_rst_i)
|
|
if (wb_rst_i)
|
|
wb_dat_o <= #1 {dw{1'b0}};
|
|
else
|
|
wb_dat_o <= #1 wb_dat;
|
|
`else
|
|
assign wb_dat_o = wb_dat;
|
|
`endif
|
|
|
|
//
|
// Generate interrupt request
|
// Generate interrupt request
|
//
|
//
|
assign wb_inta_o = ((in_pad_i ^ ~rgpio_ptrig) & rgpio_inte) ? rgpio_ctrl[`GPIO_RGPIO_CTRL_INTE] : 1'b0;
|
assign wb_inta = ((in_pad_i ^ ~rgpio_ptrig) & rgpio_inte) ? rgpio_ctrl[`GPIO_RGPIO_CTRL_INTE] : 1'b0;
|
|
|
|
//
|
|
// Optional registration of WB interrupt
|
|
//
|
|
`ifdef GPIO_REGISTERED_WB_OUTPUTS
|
|
always @(posedge wb_clk_i or posedge wb_rst_i)
|
|
if (wb_rst_i)
|
|
wb_inta_o <= #1 wb_inta;
|
|
else
|
|
wb_inta_o <= #1 wb_inta;
|
|
`else
|
|
assign wb_inta_o = wb_inta;
|
|
`endif
|
|
|
|
//
|
|
// Output enables are RGPIO_OE bits
|
|
//
|
|
assign oen_padoen_o = rgpio_oe;
|
|
|
//
|
//
|
// Generate output enables from inverted RGPIO_OE bits
|
// Generate GPIO outputs
|
//
|
//
|
assign oen_padoen_o = ~rgpio_oe;
|
assign out_pad = rgpio_out & ~rgpio_aux | aux_i & rgpio_aux;
|
|
|
//
|
//
|
// Generate outputs
|
// Optional registration of GPIO outputs
|
//
|
//
|
assign out_pad_o = rgpio_out & ~rgpio_aux | aux_i & rgpio_aux;
|
`ifdef GPIO_REGISTERED_IO_OUTPUTS
|
|
always @(posedge wb_clk_i or posedge wb_rst_i)
|
|
if (wb_rst_i)
|
|
out_pad_o <= #1 {gw{1'b0}};
|
|
else
|
|
out_pad_o <= #1 out_pad;
|
|
`else
|
|
assign out_pad_o = out_pad;
|
|
`endif
|
|
|
`else
|
`else
|
|
|
//
|
//
|
// When GPIO is not implemented, drive all outputs as would when RGPIO_CTRL
|
// When GPIO is not implemented, drive all outputs as would when RGPIO_CTRL
|