rom.sv 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // synopsys translate_off
  2. `timescale 1 ps / 1 ps
  3. // synopsys translate_on
  4. module m9k_rom (
  5. address,
  6. clock,
  7. q);
  8. parameter PROGRAM="";
  9. parameter NAME="";
  10. input [9:0] address;
  11. input clock;
  12. output [7:0] q;
  13. `ifndef ALTERA_RESERVED_QIS
  14. // synopsys translate_off
  15. `endif
  16. tri1 clock;
  17. `ifndef ALTERA_RESERVED_QIS
  18. // synopsys translate_on
  19. `endif
  20. wire [7:0] sub_wire0;
  21. wire [7:0] q = sub_wire0[7:0];
  22. initial $display("Initialising ROM Memory: %s", PROGRAM);
  23. altsyncram altsyncram_component (
  24. .address_a (address),
  25. .clock0 (clock),
  26. .q_a (sub_wire0),
  27. .aclr0 (1'b0),
  28. .aclr1 (1'b0),
  29. .address_b (1'b1),
  30. .addressstall_a (1'b0),
  31. .addressstall_b (1'b0),
  32. .byteena_a (1'b1),
  33. .byteena_b (1'b1),
  34. .clock1 (1'b1),
  35. .clocken0 (1'b1),
  36. .clocken1 (1'b1),
  37. .clocken2 (1'b1),
  38. .clocken3 (1'b1),
  39. .data_a ({8{1'b1}}),
  40. .data_b (1'b1),
  41. .eccstatus (),
  42. .q_b (),
  43. .rden_a (1'b1),
  44. .rden_b (1'b1),
  45. .wren_a (1'b0),
  46. .wren_b (1'b0));
  47. defparam
  48. altsyncram_component.address_aclr_a = "NONE",
  49. altsyncram_component.clock_enable_input_a = "BYPASS",
  50. altsyncram_component.clock_enable_output_a = "BYPASS",
  51. altsyncram_component.init_file = PROGRAM,
  52. altsyncram_component.intended_device_family = "Cyclone IV E",
  53. altsyncram_component.lpm_hint = {"ENABLE_RUNTIME_MOD=YES,INSTANCE_NAME=", NAME},
  54. altsyncram_component.lpm_type = "altsyncram",
  55. altsyncram_component.numwords_a = 1024,
  56. altsyncram_component.operation_mode = "ROM",
  57. altsyncram_component.outdata_aclr_a = "NONE",
  58. altsyncram_component.outdata_reg_a = "UNREGISTERED",
  59. altsyncram_component.ram_block_type = "M9K",
  60. altsyncram_component.widthad_a = 10,
  61. altsyncram_component.width_a = 8,
  62. altsyncram_component.width_byteena_a = 1;
  63. endmodule
  64. module pseudo_rom(addr, clk, q);
  65. parameter PROGRAM="";
  66. input reg clk;
  67. input wire [9:0] addr;
  68. output reg [7:0] q;
  69. initial $display("Initialising ROM Memory: %s", PROGRAM);
  70. reg [9:0] addr0;
  71. logic [7:0] rom [2**10:0];
  72. initial $readmemh(PROGRAM, rom);
  73. always_ff@(posedge clk) addr0 <= addr;
  74. assign q[7:0] = rom[addr0];
  75. endmodule
  76. module rom (
  77. address,
  78. clock,
  79. q);
  80. parameter PROGRAM="";
  81. input reg [11:0] address;
  82. input clock;
  83. output reg [31:0] q;
  84. reg [31:0] qn;
  85. reg [9:0] addr0, addr1, addr2, addr3;
  86. reg [11:0] a3, a2, a1;
  87. reg [7:0] q0, q1, q2, q3;
  88. reg [1:0] ar;
  89. always_ff@(posedge clock) ar <= address[1:0];
  90. always_comb begin
  91. a3 = address + 3;
  92. a2 = address + 2;
  93. a1 = address + 1;
  94. // Dividing by 4
  95. addr0 = a3[11:2];
  96. addr1 = a2[11:2];
  97. addr2 = a1[11:2];
  98. addr3 = address[11:2];
  99. case(ar)
  100. 2'b00: qn = {q3, q2, q1, q0};
  101. 2'b01: qn = {q0, q3, q2, q1};
  102. 2'b10: qn = {q1, q0, q3, q2};
  103. 2'b11: qn = {q2, q1, q0, q3};
  104. endcase
  105. q = qn;
  106. end
  107. //always_ff@(posedge clock) q <= qn;
  108. `ifdef SYNTHESIS
  109. m9k_rom#({PROGRAM, "_0.mif"}, "rom0") rom0(addr0, clock, q0);
  110. m9k_rom#({PROGRAM, "_1.mif"}, "rom1") rom1(addr1, clock, q1);
  111. m9k_rom#({PROGRAM, "_2.mif"}, "rom2") rom2(addr2, clock, q2);
  112. m9k_rom#({PROGRAM, "_3.mif"}, "rom3") rom3(addr3, clock, q3);
  113. `else
  114. pseudo_rom#({PROGRAM, "_0.mem"}) rom0(addr0, clock, q0);
  115. pseudo_rom#({PROGRAM, "_1.mem"}) rom1(addr1, clock, q1);
  116. pseudo_rom#({PROGRAM, "_2.mem"}) rom2(addr2, clock, q2);
  117. pseudo_rom#({PROGRAM, "_3.mem"}) rom3(addr3, clock, q3);
  118. // Currently read address (for debugging)
  119. reg [11:0] ff_addr;
  120. always_ff@(posedge clock) ff_addr <= address;
  121. `endif
  122. endmodule