aboutsummaryrefslogtreecommitdiff
path: root/rtl/src/ram.v
blob: 337b3e7f8735d188c3f7af5159c79fb92740298b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// ram:
// Contains data section of program and is used for stack/heap, etc.

module ram #( 
  parameter           SIZE = 1024
)(
    input             clk,
    input             rstn,
    input             we,
    input      [31:0] addr,
    input       [2:0] size,
    input      [31:0] wd,
    output reg [31:0] rd
);

`include "include/consts.vh"

//(* RAM_STYLE="BLOCK" *)
reg [31:0] mem [0:SIZE-1];

reg [31:0] rd_reg;
reg [31:0] addr_reg;


always @(posedge clk) begin
  if (we) begin
    case(size)
      FUNCT3_LS_W: mem[addr >> 2]       <= wd;
      FUNCT3_LS_H:
        case (addr[1])
          1'b0: mem[addr >> 2][15:0]    <= wd[15:0];
          1'b1: mem[addr >> 2][31:16]   <= wd[15:0];
        endcase
      FUNCT3_LS_B:
        case (addr[1:0])
          2'b00: mem[addr >> 2][7:0]    <= wd[7:0];
          2'b01: mem[addr >> 2][15:8]   <= wd[7:0];
          2'b10: mem[addr >> 2][23:16]  <= wd[7:0];
          2'b11: mem[addr >> 2][31:24]  <= wd[7:0];
        endcase
    endcase
  end
  rd_reg <= { mem[addr >> 2][31:24], mem[addr >> 2][23:16], mem[addr >> 2][15:8], mem[addr >> 2][7:0] };
  addr_reg <= addr;
end

always @ (*) begin
  case(size)
    FUNCT3_LS_W: rd = rd_reg;
    FUNCT3_LS_H:
      case (addr_reg[1])
        1'b0:  rd = { {16{rd_reg[15]}}, rd_reg[15:0] };
        1'b1:  rd = { {16{rd_reg[31]}}, rd_reg[31:16] };
      endcase
    FUNCT3_LS_B:
      case (addr_reg[1:0])
        2'b00: rd = { {24{rd_reg[7]}},  rd_reg[7:0] };
        2'b01: rd = { {24{rd_reg[15]}}, rd_reg[15:8] };
        2'b10: rd = { {24{rd_reg[23]}}, rd_reg[23:16] };
        2'b11: rd = { {24{rd_reg[31]}}, rd_reg[31:24] };
      endcase
    FUNCT3_LS_HU:
      case (addr_reg[1])
        1'b0:  rd = { {16{1'b0}}, rd_reg[15:0] };
        1'b1:  rd = { {16{1'b0}}, rd_reg[31:16] };
      endcase
    FUNCT3_LS_BU:
      case (addr_reg[1:0])
        2'b00: rd = { {24{1'b0}}, rd_reg[7:0] };
        2'b01: rd = { {24{1'b0}}, rd_reg[15:8] };
        2'b10: rd = { {24{1'b0}}, rd_reg[23:16] };
        2'b11: rd = { {24{1'b0}}, rd_reg[31:24] };
      endcase
    default:   rd = rd_reg;
  endcase
end

endmodule