| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 |
- module apb_mux #(parameter APB_CNT = 2, ADDR_BITS = 12, DATA_BITS = 32) (
- input apb_clock,
- input apb_resetn,
- input apb_in_psel,
- input apb_in_penable,
- input apb_in_pwrite,
- input [ADDR_BITS-1:0] apb_in_paddr,
- input [DATA_BITS-1:0] apb_in_pwdata,
- output reg [DATA_BITS-1:0] apb_in_prdata,
- output reg apb_in_pready,
- output reg apb_in_pslverr,
- output [APB_CNT-1:0] apb_out_psel,
- output [APB_CNT-1:0] apb_out_penable,
- output [APB_CNT-1:0] apb_out_pwrite,
- output [APB_CNT*ADDR_BITS-1:0] apb_out_paddr,
- output [APB_CNT*DATA_BITS-1:0] apb_out_pwdata,
- input [APB_CNT*DATA_BITS-1:0] apb_out_prdata,
- input [APB_CNT-1:0] apb_out_pready,
- input [APB_CNT-1:0] apb_out_pslverr,
- input [APB_CNT-1:0] apb_select
- );
- genvar i;
- generate
- for (i = 0; i < APB_CNT; i = i + 1) begin : gen_per
- assign apb_out_psel[i] = apb_in_psel & apb_select[i];
- assign apb_out_penable[i] = apb_in_penable & apb_select[i];
- assign apb_out_pwrite[i] = apb_in_pwrite;
- assign apb_out_paddr[i*ADDR_BITS+:ADDR_BITS] = apb_in_paddr;
- assign apb_out_pwdata[i*DATA_BITS+:DATA_BITS] = apb_in_pwdata;
- end
- endgenerate
- reg [APB_CNT-1:0] pr_select; // These extra registers provide better timing to apb_in_prdata
- always @ (posedge apb_clock or negedge apb_resetn) begin
- if (!apb_resetn) begin
- pr_select <= 'b0;
- end else if (apb_in_psel && !apb_in_penable) begin
- pr_select <= apb_select;
- end
- end
- integer j;
- always @ (*) begin
- apb_in_prdata = 0;
- apb_in_pready = 1;
- apb_in_pslverr = 0;
- for (j = 0; j < APB_CNT; j = j + 1) begin
- apb_in_prdata = apb_in_prdata | (pr_select[j] ? apb_out_prdata[j*DATA_BITS+:DATA_BITS] : 0);
- apb_in_pready = apb_in_pready & (pr_select[j] ? apb_out_pready[j] : 1'b1);
- apb_in_pslverr = apb_in_pslverr | (pr_select[j] ? apb_out_pslverr[j] : 1'b0);
- end
- end
- endmodule
|