Line 1... |
Line 1... |
/*
|
/*
|
*
|
*
|
* Simple 8-bit wide GPIO module
|
* Simple 24-bit wide GPIO module
|
*
|
*
|
* Can be made wider as needed, but must be done manually.
|
* Can be made wider as needed, but must be done manually.
|
*
|
*
|
* First lot of bytes are the GPIO I/O regs
|
* First lot of bytes are the GPIO I/O regs
|
* Second lot are the direction registers
|
* Second lot are the direction registers
|
Line 11... |
Line 11... |
*
|
*
|
* Register mapping:
|
* Register mapping:
|
*
|
*
|
* For 8 GPIOs we would have
|
* For 8 GPIOs we would have
|
* adr 0: gpio data 7:0
|
* adr 0: gpio data 7:0
|
* adr 1: gpio dir 7:0
|
|
*
|
|
*
|
|
* So for 24 GPIOs we would have
|
|
* adr 0: gpio data 7:0
|
|
* adr 1: gpio data 15:8
|
* adr 1: gpio data 15:8
|
* adr 2: gpio data 24:16
|
* adr 2: gpio data 23:16
|
* adr 3: gpio dir 7:0
|
* adr 3: gpio dir 7:0
|
* adr 4: gpio dir 15:8
|
* adr 4: gpio dir 15:8
|
* adr 5: gpio dir 24:16
|
* adr 5: gpio dir 23:16
|
*
|
|
* Obviously any width where width%8!=0 you must skip the remainder of the byte
|
|
* before starting the dir registers.
|
|
*
|
*
|
* Backend pinout file needs to be updated for any GPIO width changes.
|
* Backend pinout file needs to be updated for any GPIO width changes.
|
*
|
*
|
*/
|
*/
|
|
|
Line 49... |
Line 41... |
wb_rty_o,
|
wb_rty_o,
|
|
|
gpio_io);
|
gpio_io);
|
|
|
|
|
parameter gpio_io_width = 8;
|
parameter gpio_io_width = 24;
|
|
|
parameter gpio_dir_reset_val = 0;
|
parameter gpio_dir_reset_val = 0;
|
parameter gpio_o_reset_val = 0;
|
parameter gpio_o_reset_val = 0;
|
|
|
|
|
Line 91... |
Line 83... |
assign gpio_io[i] = (gpio_dir[i]) ? gpio_o[i] : 1'bz;
|
assign gpio_io[i] = (gpio_dir[i]) ? gpio_o[i] : 1'bz;
|
assign gpio_i[i] = (gpio_dir[i]) ? gpio_o[i] : gpio_io[i];
|
assign gpio_i[i] = (gpio_dir[i]) ? gpio_o[i] : gpio_io[i];
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
|
// GPIO data out register
|
// GPIO dir register
|
|
always @(posedge wb_clk)
|
always @(posedge wb_clk)
|
if (wb_rst)
|
if (wb_rst)
|
gpio_dir <= 0; // All set to in at reset
|
gpio_o <= 0; // All set to in at reset
|
else if (wb_stb_i & wb_we_i)
|
else if (wb_stb_i & wb_we_i)
|
begin
|
begin
|
if (wb_adr_i == ((gpio_io_width/8)))
|
if (wb_adr_i == 0)
|
gpio_dir[7:0] <= wb_dat_i;
|
gpio_o[7:0] <= wb_dat_i;
|
/*
|
if (wb_adr_i == 1)
|
if (wb_adr_i == ((gpio_io_width/8)+1))
|
gpio_o[15:8] <= wb_dat_i;
|
gpio_dir[15:8] <= wb_dat_i;
|
if (wb_adr_i == 2)
|
if (wb_adr_i == ((gpio_io_width/8)+2))
|
gpio_o[23:16] <= wb_dat_i;
|
//gpio_dir[23:16] <= wb_dat_i;
|
|
gpio_dir[21:16] <= wb_dat_i[5:0];
|
|
*/
|
|
/* Add appropriate address detection here for wider GPIO */
|
/* Add appropriate address detection here for wider GPIO */
|
|
|
end
|
end
|
|
|
|
|
// GPIO data out register
|
// GPIO dir register
|
always @(posedge wb_clk)
|
always @(posedge wb_clk)
|
if (wb_rst)
|
if (wb_rst)
|
gpio_o <= 0; // All set to in at reset
|
gpio_dir <= 0; // All set to in at reset
|
else if (wb_stb_i & wb_we_i)
|
else if (wb_stb_i & wb_we_i)
|
begin
|
begin
|
if (wb_adr_i == 0)
|
if (wb_adr_i == ((gpio_io_width/8)))
|
gpio_o[7:0] <= wb_dat_i;
|
gpio_dir[7:0] <= wb_dat_i;
|
/*
|
if (wb_adr_i == ((gpio_io_width/8)+1))
|
if (wb_adr_i == 1)
|
gpio_dir[15:8] <= wb_dat_i;
|
gpio_o[15:8] <= wb_dat_i;
|
if (wb_adr_i == ((gpio_io_width/8)+2))
|
if (wb_adr_i == 2)
|
//gpio_dir[23:16] <= wb_dat_i;
|
gpio_o[23:16] <= wb_dat_i;
|
gpio_dir[21:16] <= wb_dat_i[5:0];
|
*/
|
|
/* Add appropriate address detection here for wider GPIO */
|
/* Add appropriate address detection here for wider GPIO */
|
end
|
|
|
|
|
end
|
|
|
// Register the gpio in signal
|
// Register the gpio in signal
|
always @(posedge wb_clk)
|
always @(posedge wb_clk)
|
begin
|
begin
|
// Data regs
|
// Data regs
|
if (wb_adr_i == 0)
|
if (wb_adr_i == 0)
|
wb_dat_o[7:0] <= gpio_i[7:0];
|
wb_dat_o[7:0] <= gpio_i[7:0];
|
/*
|
if (wb_adr_i == 1)
|
if (wb_adr_i == 1)
|
wb_dat_o[7:0] <= gpio_i[15:8];
|
wb_dat_o[7:0] <= gpio_i[15:8];
|
if (wb_adr_i == 2)
|
if (wb_adr_i == 2)
|
wb_dat_o[7:0] <= gpio_i[23:16];
|
wb_dat_o[7:0] <= gpio_i[23:16];
|
|
*/
|
|
/* Add appropriate address detection here for wider GPIO */
|
/* Add appropriate address detection here for wider GPIO */
|
// Direction regs
|
// Direction regs
|
if (wb_adr_i == 1)
|
if (wb_adr_i == ((gpio_io_width/8)))
|
wb_dat_o[7:0] <= gpio_dir[7:0];
|
wb_dat_o[7:0] <= gpio_dir[7:0];
|
/*
|
if (wb_adr_i == ((gpio_io_width/8)+1))
|
if (wb_adr_i == 4)
|
wb_dat_o[7:0] <= gpio_dir[15:8];
|
wb_dat_o[7:0] <= gpio_dir[15:8];
|
if (wb_adr_i == ((gpio_io_width/8)+2))
|
if (wb_adr_i == 5)
|
wb_dat_o[7:0] <= gpio_dir[23:16];
|
wb_dat_o[7:0] <= gpio_dir[23:16];
|
|
*/
|
|
/* Add appropriate address detection here for wider GPIO */
|
/* Add appropriate address detection here for wider GPIO */
|
|
|
end
|
end
|
|
|
|
|