apb_mux.v 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. module apb_mux #(parameter APB_CNT = 2, ADDR_BITS = 12, DATA_BITS = 32) (
  2. input apb_clock,
  3. input apb_resetn,
  4. input apb_in_psel,
  5. input apb_in_penable,
  6. input apb_in_pwrite,
  7. input [ADDR_BITS-1:0] apb_in_paddr,
  8. input [DATA_BITS-1:0] apb_in_pwdata,
  9. output reg [DATA_BITS-1:0] apb_in_prdata,
  10. output reg apb_in_pready,
  11. output reg apb_in_pslverr,
  12. output [APB_CNT-1:0] apb_out_psel,
  13. output [APB_CNT-1:0] apb_out_penable,
  14. output [APB_CNT-1:0] apb_out_pwrite,
  15. output [APB_CNT*ADDR_BITS-1:0] apb_out_paddr,
  16. output [APB_CNT*DATA_BITS-1:0] apb_out_pwdata,
  17. input [APB_CNT*DATA_BITS-1:0] apb_out_prdata,
  18. input [APB_CNT-1:0] apb_out_pready,
  19. input [APB_CNT-1:0] apb_out_pslverr,
  20. input [APB_CNT-1:0] apb_select
  21. );
  22. genvar i;
  23. generate
  24. for (i = 0; i < APB_CNT; i = i + 1) begin : gen_per
  25. assign apb_out_psel[i] = apb_in_psel & apb_select[i];
  26. assign apb_out_penable[i] = apb_in_penable & apb_select[i];
  27. assign apb_out_pwrite[i] = apb_in_pwrite;
  28. assign apb_out_paddr[i*ADDR_BITS+:ADDR_BITS] = apb_in_paddr;
  29. assign apb_out_pwdata[i*DATA_BITS+:DATA_BITS] = apb_in_pwdata;
  30. end
  31. endgenerate
  32. reg [APB_CNT-1:0] pr_select; // These extra registers provide better timing to apb_in_prdata
  33. always @ (posedge apb_clock or negedge apb_resetn) begin
  34. if (!apb_resetn) begin
  35. pr_select <= 'b0;
  36. end else if (apb_in_psel && !apb_in_penable) begin
  37. pr_select <= apb_select;
  38. end
  39. end
  40. integer j;
  41. always @ (*) begin
  42. apb_in_prdata = 0;
  43. apb_in_pready = 1;
  44. apb_in_pslverr = 0;
  45. for (j = 0; j < APB_CNT; j = j + 1) begin
  46. apb_in_prdata = apb_in_prdata | (pr_select[j] ? apb_out_prdata[j*DATA_BITS+:DATA_BITS] : 0);
  47. apb_in_pready = apb_in_pready & (pr_select[j] ? apb_out_pready[j] : 1'b1);
  48. apb_in_pslverr = apb_in_pslverr | (pr_select[j] ? apb_out_pslverr[j] : 1'b0);
  49. end
  50. end
  51. endmodule