aboutsummaryrefslogtreecommitdiffstats
path: root/extram/extram_wb.v
blob: c8428783a81cae44ee832d8d3dfce7d8a96ceb5f (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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
module extram_wb
  #(parameter PAGE_SIZE = 10,
    parameter ADDR_WIDTH = 16)
    (input clk, input rst,
     input wb_clk, input wb_rst,
     input cyc_i, input stb_i,
     input [ADDR_WIDTH-1:0] adr_i,
     input we_i,
     input [31:0] dat_i,
     output reg [31:0] dat_o,
     output reg ack_o,
     
     inout [17:0] RAM_D,
     output [PAGE_SIZE-2:0] RAM_A,
     output RAM_CE1n, output RAM_CENn,
     output RAM_CLK, output RAM_WEn,
     output RAM_OEn, output RAM_LDn );

   wire     read_acc = stb_i & cyc_i & ~we_i;
   wire     write_acc = stb_i & cyc_i & we_i;
   wire     acc = stb_i & cyc_i;

   assign   RAM_CLK = ~wb_clk;   // 50 MHz for now, eventually should be 200 MHz
   assign   RAM_LDn = 0;        // No burst for now
   assign   RAM_CENn = 0;       // Use CE1n as our main CE

   reg [PAGE_SIZE-2:1] RAM_addr_reg;
   always @(posedge wb_clk)
     if(acc)
       RAM_addr_reg[PAGE_SIZE-2:1] <= adr_i[PAGE_SIZE-1:2];
   assign 	       RAM_A[PAGE_SIZE-2:1] = RAM_addr_reg; 

   reg [31:0] 	       ram_out;
   always @(posedge wb_clk)
     if(write_acc)
       ram_out <= dat_i;

   // RAM access state machine
   localparam RAM_idle = 0;
   localparam RAM_read_1 = 1;
   localparam RAM_read_2 = 2;
   localparam RAM_read_3 = 3;
   localparam RAM_read_4 = 4;
   localparam RAM_write_1 = 6;
   localparam RAM_write_2 = 7;
   localparam RAM_write_3 = 8;
   localparam RAM_write_4 = 9;

   reg 	      myOE = 0;
   reg 	      RAM_OE = 0;
   reg 	      RAM_WE = 0;
   reg 	      RAM_EN = 0;
   reg 	      RAM_A0_reg;
   reg [3:0]  RAM_state;
   
   always @(posedge wb_clk)
     if(wb_rst)
       begin
	  RAM_state <= RAM_idle;
	  myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
       end
     else
       case(RAM_state)
	 RAM_idle :
	   if(read_acc & ~ack_o)
	     begin
		RAM_state <= RAM_read_1;
		myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 1; RAM_A0_reg <= 0;
	     end
	   else if(write_acc & ~ack_o)
	     begin
		RAM_state <= RAM_write_1;
		myOE <= 0; RAM_OE <= 0; RAM_WE <= 1; RAM_EN <= 1; RAM_A0_reg <= 0;
	     end
	   else
	     begin
		myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
	     end
	 RAM_read_1 : 
	   begin
	      RAM_state <= RAM_read_2;
	      myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 1; RAM_A0_reg <= 1;
	   end
	 RAM_read_2 : 
	   begin
	      RAM_state <= RAM_read_3;
	      myOE <= 0; RAM_OE <= 1; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
	   end
	 RAM_read_3 : 
	   begin
	      RAM_state <= RAM_read_4;
	      myOE <= 0; RAM_OE <= 1; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
	   end
	 RAM_read_4 :
	   begin
	      RAM_state <= RAM_idle;
	      myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
	   end
	 RAM_write_1 : 
	   begin
	      RAM_state <= RAM_write_2;
	      myOE <= 1; RAM_OE <= 0; RAM_WE <= 1; RAM_EN <= 1; RAM_A0_reg <= 1;
	   end
	 RAM_write_2 : 
	   begin
	      RAM_state <= RAM_write_3;
	      myOE <= 1; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
	   end
	 RAM_write_3 : 
	   begin
	      RAM_state <= RAM_write_4;
	      myOE <= 1; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
	   end
	 RAM_write_4 : 
	   begin
	      RAM_state <= RAM_idle;
	      myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
	   end
	 default : RAM_state <= RAM_idle;
       endcase // case(RAM_state)
   
   assign     RAM_A[0] = RAM_A0_reg;
   assign     RAM_WEn = ~RAM_WE;  // ((RAM_state==RAM_write_1)||(RAM_state==RAM_write_2));
   assign     RAM_OEn = ~RAM_OE;
   assign     RAM_CE1n = ~RAM_EN;    // Active low     (RAM_state != RAM_idle);
   
   assign     RAM_D[17:16] = 2'bzz;
   assign     RAM_D[15:0] = myOE ? ((RAM_state==RAM_write_2)?ram_out[15:0]:ram_out[31:16]) 
	      : 16'bzzzz_zzzz_zzzz_zzzz;

   always @(posedge wb_clk)
     if(RAM_state == RAM_read_3)
       dat_o[15:0] <= RAM_D[15:0];
     else
       dat_o[31:16] <= RAM_D[15:0];
   
   always @(posedge wb_clk)
     if(wb_rst)
       ack_o <= 0;
     else if((RAM_state == RAM_write_4)||(RAM_state == RAM_read_4))
       ack_o <= 1;
     else
       ack_o <= 0;
   
endmodule // extram_wb