InstrMem.v 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /*
  2. * Instruction Memory
  3. */
  4. module InstrMem(
  5. input clk,
  6. input reset,
  7. input [31:0] addr,
  8. output hit,
  9. output [31:0] q,
  10. // bus
  11. output [31:0] bus_addr,
  12. output [31:0] bus_data,
  13. output bus_we,
  14. output reg bus_start,
  15. input [31:0] bus_q,
  16. input bus_done,
  17. input bus_ready,
  18. input clear, hold
  19. );
  20. // in case of a clear mid transaction, ignore the next result and start again
  21. reg ignoreNext = 1'b0;
  22. reg [31:0] addr_prev = 32'd0;
  23. reg hit_prev = 1'b0;
  24. reg hold_reg = 1'b0;
  25. assign hit = (bus_done && !ignoreNext && !clear) || (hold_reg && hit_prev);
  26. assign q = (hit_prev) ? bus_q : 32'd0;
  27. assign bus_addr = addr;
  28. assign bus_data = 32'd0;
  29. assign bus_we = 1'b0;
  30. reg bus_start_prev = 1'b0;
  31. always @(posedge clk)
  32. begin
  33. if (reset)
  34. ignoreNext <= 1'b0;
  35. else if (ignoreNext && (bus_done || bus_ready))
  36. ignoreNext <= 1'b0;
  37. else if (clear && (bus_start || !bus_ready))
  38. ignoreNext <= 1'b1;
  39. end
  40. always @(posedge clk)
  41. begin
  42. if (reset)
  43. begin
  44. bus_start <= 0;
  45. bus_start_prev <= 0;
  46. addr_prev <= 32'd0;
  47. hit_prev <= 1'b0;
  48. hold_reg <= 1'b0;
  49. end
  50. else
  51. begin
  52. if (!hold && !clear && ((bus_done || hit) || addr == 0 || ignoreNext))
  53. begin
  54. bus_start <= 1'b1;
  55. end
  56. else
  57. bus_start <= 1'b0;
  58. addr_prev <= addr;
  59. bus_start_prev <= bus_start;
  60. hit_prev <= hit;
  61. if (hold)
  62. hold_reg <= 1'b1;
  63. else
  64. hold_reg <= 1'b0;
  65. end
  66. end
  67. endmodule