blob: 9236bebb5e933ba6f0d99211d5de7442a24e9edc [file] [log] [blame]
shalan0d14e6e2020-08-31 16:50:48 +02001module mprj_ctrl_wb #(
2 parameter BASE_ADR = 32'h 2300_0000,
3 parameter IO_PADS = 32, // Number of IO control registers
4 parameter PWR_CTRL = 32 // Number of power control registers
5)(
6 input wb_clk_i,
7 input wb_rst_i,
8
9 input [31:0] wb_dat_i,
10 input [31:0] wb_adr_i,
11 input [3:0] wb_sel_i,
12 input wb_cyc_i,
13 input wb_stb_i,
14 input wb_we_i,
15
16 output [31:0] wb_dat_o,
17 output wb_ack_o,
18
19 output [IO_PADS-1:0] output_en_n,
20 output [IO_PADS-1:0] holdh_n,
21 output [IO_PADS-1:0] enableh,
22 output [IO_PADS-1:0] input_dis,
23 output [IO_PADS-1:0] ib_mode_sel,
24 output [IO_PADS-1:0] analog_en,
25 output [IO_PADS-1:0] analog_sel,
26 output [IO_PADS-1:0] analog_pol,
27 output [IO_PADS*3-1:0] digital_mode
28);
29
30 wire resetn;
31 wire valid;
32 wire ready;
33 wire [3:0] iomem_we;
34
35 assign resetn = ~wb_rst_i;
36 assign valid = wb_stb_i && wb_cyc_i;
37
38 assign iomem_we = wb_sel_i & {4{wb_we_i}};
39 assign wb_ack_o = ready;
40
41 mprj_ctrl #(
42 .BASE_ADR(BASE_ADR),
43 .IO_PADS(IO_PADS),
44 .PWR_CTRL(PWR_CTRL)
45 ) mprj_ctrl (
46 .clk(wb_clk_i),
47 .resetn(resetn),
48 .iomem_addr(wb_adr_i),
49 .iomem_valid(valid),
50 .iomem_wstrb(iomem_we),
51 .iomem_wdata(wb_dat_i),
52 .iomem_rdata(wb_dat_o),
53 .iomem_ready(ready),
54 .output_en_n(output_en_n),
55 .holdh_n(holdh_n),
56 .enableh(enableh),
57 .input_dis(input_dis),
58 .ib_mode_sel(ib_mode_sel),
59 .analog_en(analog_en),
60 .analog_sel(analog_sel),
61 .analog_pol(analog_pol),
62 .digital_mode(digital_mode)
63 );
64
65endmodule
66
67module mprj_ctrl #(
68 parameter BASE_ADR = 32'h 2300_0000,
69 parameter IO_PADS = 32,
70 parameter PWR_CTRL = 32
71)(
72 input clk,
73 input resetn,
74
75 input [31:0] iomem_addr,
76 input iomem_valid,
77 input [3:0] iomem_wstrb,
78 input [31:0] iomem_wdata,
79
80 output reg [31:0] iomem_rdata,
81 output reg iomem_ready,
82
83 output [IO_PADS-1:0] output_en_n,
84 output [IO_PADS-1:0] holdh_n,
85 output [IO_PADS-1:0] enableh,
86 output [IO_PADS-1:0] input_dis,
87 output [IO_PADS-1:0] ib_mode_sel,
88 output [IO_PADS-1:0] analog_en,
89 output [IO_PADS-1:0] analog_sel,
90 output [IO_PADS-1:0] analog_pol,
91 output [IO_PADS*3-1:0] digital_mode
92);
93
94 localparam PWR_BASE_ADR = BASE_ADR + IO_PADS*4;
95 localparam OEB = 0;
96 localparam HLDH = 1;
97 localparam ENH = 2;
98 localparam INP_DIS = 3;
99 localparam MOD_SEL = 4;
100 localparam AN_EN = 5;
101 localparam AN_SEL = 6;
102 localparam AN_POL = 7;
103 localparam DM = 8;
104
105 reg [IO_PADS*32-1:0] io_ctrl;
106 reg [PWR_CTRL*32-1:0] pwr_ctrl;
107
108 wire [IO_PADS-1:0] io_ctrl_sel;
109 wire [PWR_CTRL-1:0] pwr_ctrl_sel;
110
111 genvar i;
112 generate
113 for (i=0; i<IO_PADS; i=i+1) begin
114 assign io_ctrl_sel[i] = (iomem_addr[7:0] == (BASE_ADR[7:0] + i*4));
115 assign output_en_n[i] = io_ctrl[i*32+OEB];
116 assign holdh_n[i] = io_ctrl[i*32+HLDH];
117 assign enableh[i] = io_ctrl[i*32+ENH];
118 assign input_dis[i] = io_ctrl[i*32+INP_DIS];
119 assign ib_mode_sel[i] = io_ctrl[i*32+MOD_SEL];
120 assign analog_en[i] = io_ctrl[i*32+AN_EN];
121 assign analog_sel[i] = io_ctrl[i*32+AN_SEL];
122 assign analog_pol[i] = io_ctrl[i*32+AN_POL];
123 assign digital_mode[(i+1)*3-1:i*3] = io_ctrl[i*32+DM+3-1:i*32+DM];
124 end
125 endgenerate
126
127 generate
128 for (i=0; i<PWR_CTRL; i=i+1) begin
129 assign pwr_ctrl_sel[i] = (iomem_addr[7:0] == (PWR_BASE_ADR[7:0] + i*4));
130 end
131 endgenerate
132
133 generate
134 for (i=0; i<IO_PADS; i=i+1) begin
135 always @(posedge clk) begin
136 if (!resetn) begin
137 io_ctrl[i*32+: 32] <= 0;
138 end else begin
139 iomem_ready <= 0;
140 if (iomem_valid && !iomem_ready && iomem_addr[31:8] == BASE_ADR[31:8]) begin
141 iomem_ready <= 1'b 1;
142
143 if (io_ctrl_sel[i]) begin
144 iomem_rdata <= io_ctrl[i*32+: 32];
145 if (iomem_wstrb[0])
146 io_ctrl[(i+1)*32-1-24:i*32] <= iomem_wdata[7:0];
147
148 if (iomem_wstrb[1])
149 io_ctrl[(i+1)*32-1-16:i*32+8] <= iomem_wdata[15:8];
150
151 if (iomem_wstrb[2])
152 io_ctrl[(i+1)*32-1-8:i*32+16] <= iomem_wdata[23:16];
153
154 if (iomem_wstrb[3])
155 io_ctrl[(i+1)*32-1:i*32+24] <= iomem_wdata[31:24];
156 end
157 end
158 end
159 end
160 end
161 endgenerate
162
163 generate
164 for (i=0; i<PWR_CTRL; i=i+1) begin
165 always @(posedge clk) begin
166 if (!resetn) begin
167 pwr_ctrl[i*32+: 32] <= 0;
168 end else begin
169 iomem_ready <= 0;
170 if (iomem_valid && !iomem_ready && iomem_addr[31:8] == BASE_ADR[31:8]) begin
171 iomem_ready <= 1'b 1;
172
173 if (pwr_ctrl_sel[i]) begin
174 iomem_rdata <= pwr_ctrl[i*32+: 32];
175 if (iomem_wstrb[0])
176 pwr_ctrl[(i+1)*32-1-24:i*32] <= iomem_wdata[7:0];
177
178 if (pwr_ctrl_sel[1])
179 pwr_ctrl[(i+1)*32-1-16:i*32+8] <= iomem_wdata[15:8];
180
181 if (pwr_ctrl_sel[2])
182 pwr_ctrl[(i+1)*32-1-8:i*32+16] <= iomem_wdata[23:16];
183
184 if (pwr_ctrl_sel[3])
185 pwr_ctrl[(i+1)*32-1:i*32+24] <= iomem_wdata[31:24];
186 end
187 end
188 end
189 end
190 end
191 endgenerate
192
193endmodule