Arbiter.v 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /*
  2. * Arbiter
  3. * Regulates access to the CPU memory bus from both Instruction and Data memory
  4. * Port a (instruction memory) will directly access the bus (no latency)
  5. * When port b (data memory) requests an access, it will stop port a when it is finished and give access to port b
  6. * This will give port b quite some latency, but as port b requests are more rare, this should be okay (and can be reduced by l1d cache)
  7. */
  8. module Arbiter(
  9. input clk,
  10. input reset,
  11. // port a (Instr)
  12. input [31:0] addr_a,
  13. input [31:0] data_a,
  14. input we_a,
  15. input start_a,
  16. output done_a,
  17. // port b (Data)
  18. input [31:0] addr_b,
  19. input [31:0] data_b,
  20. input we_b,
  21. input start_b,
  22. output done_b,
  23. // output (both ports)
  24. output [31:0] q,
  25. // bus
  26. output [26:0] bus_addr,
  27. output [31:0] bus_data,
  28. output bus_we ,
  29. output bus_start,
  30. input [31:0] bus_q,
  31. input bus_done
  32. );
  33. assign q = bus_q;
  34. assign bus_addr = (!port_b_access) ? addr_a : bus_addr_reg;
  35. assign bus_data = (!port_b_access) ? data_a : bus_data_reg;
  36. assign bus_we = (!port_b_access) ? we_a : bus_we_reg;
  37. assign bus_start = (!port_b_access) ? start_a : (bus_start_reg && !bus_done);
  38. assign done_a = (!port_b_access) && bus_done;
  39. assign done_b = (state == state_wait_b_done) && bus_done;
  40. reg port_b_access = 1'b0;
  41. reg [26:0] bus_addr_reg = 27'd0;
  42. reg [31:0] bus_data_reg = 32'd0;
  43. reg bus_we_reg = 1'b0;
  44. reg bus_start_reg = 1'b0;
  45. // state machine
  46. reg [2:0] state = 3'd0; // 0-7 states limit
  47. parameter state_idle = 3'd0;
  48. parameter state_wait_b_done = 3'd1;
  49. always @(posedge clk)
  50. begin
  51. if (reset)
  52. begin
  53. port_b_access <= 1'b0;
  54. bus_addr_reg <= 27'd0;
  55. bus_data_reg <= 32'd0;
  56. bus_we_reg <= 1'b0;
  57. bus_start_reg <= 1'b0;
  58. state <= state_idle;
  59. end
  60. else
  61. begin
  62. case(state)
  63. state_idle:
  64. begin
  65. // if port b is requested and port a is just finished
  66. if (!start_a && bus_done && start_b)
  67. begin
  68. // give access to port b before a starts a new request
  69. port_b_access <= 1'b1;
  70. bus_addr_reg <= addr_b;
  71. bus_data_reg <= data_b;
  72. bus_we_reg <= we_b;
  73. bus_start_reg <= 1'b1;
  74. state <= state_wait_b_done;
  75. end
  76. end
  77. state_wait_b_done:
  78. begin
  79. if (bus_done)
  80. begin
  81. // return access to port a
  82. state <= state_idle;
  83. port_b_access <= 1'b0;
  84. end
  85. end
  86. endcase
  87. end
  88. end
  89. endmodule