fast_mem.sv 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. //
  2. // Fast local memory for the internal CPU.
  3. // This allows unaligned accesses as given by the byte enables.
  4. //
  5. module fast_mem #(
  6. parameter bits = 11, // Power of 2 number of words
  7. parameter string mif
  8. )
  9. (
  10. input rst_n,
  11. input clk,
  12. input read,
  13. input write,
  14. input [7:0] be,
  15. input [bits-1:0] addr,
  16. input [31:0] wdata,
  17. output reg [31:0] rdata
  18. );
  19. localparam words = 1 << bits;
  20. // The actual memory arrays
  21. (* ramstyle = "no_rw_check", ram_init_file = {mif, ".0.mif"} *)
  22. reg [7:0] mem0[0:words-1];
  23. (* ramstyle = "no_rw_check", ram_init_file = {mif, ".1.mif"} *)
  24. reg [7:0] mem1[0:words-1];
  25. (* ramstyle = "no_rw_check", ram_init_file = {mif, ".2.mif"} *)
  26. reg [7:0] mem2[0:words-1];
  27. (* ramstyle = "no_rw_check", ram_init_file = {mif, ".3.mif"} *)
  28. reg [7:0] mem3[0:words-1];
  29. always @(posedge clk)
  30. begin
  31. // Ignore the write signal if reset is active!
  32. if (write & rst_n)
  33. begin
  34. if (be[0] | be[4]) mem0[addr + be[4]] <= wdata[ 7: 0];
  35. if (be[1] | be[5]) mem1[addr + be[5]] <= wdata[15: 8];
  36. if (be[2] | be[6]) mem2[addr + be[6]] <= wdata[23:16];
  37. if (be[3] | be[7]) mem3[addr + be[7]] <= wdata[31:24];
  38. end
  39. rdata[ 7: 0] <= mem0[addr + be[4]];
  40. rdata[15: 8] <= mem1[addr + be[5]];
  41. rdata[23:16] <= mem2[addr + be[6]];
  42. rdata[31:24] <= mem3[addr + be[7]];
  43. end // always_ff @ (posedge clk)
  44. endmodule // fast_mem