aboutsummaryrefslogtreecommitdiff
path: root/design/sram_slave.v
blob: 718ef8a73397711f81d07de7777e246498f7b6ff (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
`default_nettype none

module sram_slave
  (
   /* Interface to memory */
   output wire [17:0] sram_addr,
   inout wire [15:0]  sram_io,

   output wire 	      sram_cs_n,
   output wire 	      sram_oe_n,
   output wire 	      sram_we_n,

   /* Wishbone slave interface */
   output wire 	      ACK_O,
   input wire [17:0]  ADR_I,
   input wire 	      CLK_I,
   input wire [15:0]  DAT_I,
   output wire [15:0] DAT_O,
   input wire 	      RST_I,
   input wire 	      STB_I,
   input wire 	      WE_I,
   output wire 	      STALL_O
   );

   reg 		      writing;
   reg [15:0] 	      write_data;
   assign sram_io = sram_we_n ? 16'hZZZZ : write_data;

   reg 		      sram_cs_not;
   reg 		      sram_oe_not;
   reg 		      sram_we_not;
   assign sram_cs_n = sram_cs_not;
   assign sram_oe_n = sram_oe_not;
   assign sram_we_n = sram_we_not;

   reg [17:0] 	      address;
   assign sram_addr = address;

   reg 		      ack;
   assign ACK_O = ack;

   reg 		      stall;
   assign STALL_O = stall;

   reg [15:0] 	      output_data;
   assign DAT_O = output_data;

   reg [2:0] 	      state;

   always @ (posedge CLK_I) begin
      output_data <= sram_io;

      if (RST_I) begin
	 sram_cs_not <= 1;
	 sram_oe_not <= 1;
	 writing <= 0;

	 ack <= 0;
	 stall <= 0;

	 state <= 0;
      end else begin
	 if (state == 0 || state == 2) begin /* possibly starting new job */
	    if (STB_I) begin
	       address <= ADR_I;

	       sram_cs_not <= 0;
	       sram_oe_not <= WE_I;
	       writing <= WE_I;
	       write_data <= DAT_I;

	       state <= WE_I ? 1 : 2;
	       stall <= WE_I ? 1 : 0;
	    end else begin // if (STB_I)
	       sram_cs_not <= 1;
	       sram_oe_not <= 1;
	       writing <= 0;

	       state <= 0;
	    end
	 end // if (state == 0 || state == 2)

	 if (state == 1) begin /* performing write; it takes 2 CLK_I cycles */
	    state <= 2;
	    stall <= 0;
	 end

	 if (state == 2) begin /* finishing job */
	    ack <= 1;
	 end else begin
	    ack <= 0;
	 end
      end
   end // always @ (posedge CLK_I)

   /*
    * avoid bus congestion by only driving sram_io
    * during the middle part of write cycle
    */
   always @ (negedge CLK_I) begin
      if (writing)
	sram_we_not <= !sram_we_not;
      else
	sram_we_not <= 1;
   end
endmodule // sram_slave