aboutsummaryrefslogtreecommitdiff
path: root/design/interface_wrapper.v
blob: 30d2e49a076f43b3cc8a75a8fc55e9fcf129564b (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
/*
 * For now, this wrapper ignores SEL_O signals - we'll update it for
 * byte-granular accesses later.
 */
`default_nettype none

module interface_wrapper
  (
   input wire 	      CLK_I,
   input wire 	      RST_I,

   output wire 	      RAW_ACK_I,
   output wire 	      RAW_ERR_I, /* We'll start using it soon */
   input wire [20:0]  RAW_ADR_O,
   output wire [31:0] RAW_DAT_I,
   input wire [31:0]  RAW_DAT_O,
   input wire [3:0]   RAW_SEL_O, /* We'll start using it soon */
   input wire 	      RAW_STB_O,
   input wire 	      RAW_CYC_O,
   input wire 	      RAW_WE_O,
   output wire 	      RAW_STALL_I,

   input wire 	      WRAPPED_ACK_I,
   output wire [19:0] WRAPPED_ADR_O,
   input wire [15:0]  WRAPPED_DAT_I,
   output wire [15:0] WRAPPED_DAT_O,
   output wire 	      WRAPPED_STB_O,
   output wire 	      WRAPPED_CYC_O,
   output wire 	      WRAPPED_WE_O,
   input wire 	      WRAPPED_STALL_I
   );

   /* RAW -> WRAPPED */
   wire 	      wrapped_request_happens;
   assign wrapped_request_happens = WRAPPED_STB_O && !WRAPPED_STALL_I;

   wire 	      raw_request_wanted;
   assign raw_request_wanted = RAW_STB_O && RAW_CYC_O;

   reg [19:0] 	      ADR_O_waiting;
   reg [31:0] 	      DAT_O_waiting;
   reg 		      WE_O_waiting;
   reg [1:0] 	      request_out_waiting;

   wire 	      can_accept_request;
   assign can_accept_request = !request_out_waiting[0] ||
			       (!request_out_waiting[1] &&
				wrapped_request_happens);

   assign WRAPPED_ADR_O = request_out_waiting[0] ?
			  ADR_O_waiting : RAW_ADR_O >> 1;
   assign WRAPPED_DAT_O = request_out_waiting[0] ?
			  DAT_O_waiting[15:0] : RAW_DAT_O[15:0];
   assign WRAPPED_WE_O = request_out_waiting[0] ?
			 WE_O_waiting : RAW_WE_O;
   assign WRAPPED_STB_O = request_out_waiting[0] || raw_request_wanted;

   assign WRAPPED_CYC_O = RAW_CYC_O;

   always @ (posedge CLK_I) begin
      if (RST_I) begin
	 ADR_O_waiting <= 20'bx;
	 DAT_O_waiting <= 32'bx;
	 WE_O_waiting <= 1'bx;
	 request_out_waiting <= 2'b0;
      end else begin
	 if (wrapped_request_happens) begin
	    if (request_out_waiting[1]) begin
	       ADR_O_waiting <= ADR_O_waiting + 1;
	       DAT_O_waiting <= {16'bx, DAT_O_waiting[31:16]};
	       request_out_waiting <= {1'b0, request_out_waiting[1]};
	    end else begin
	       ADR_O_waiting <= RAW_ADR_O >> 1;
	       WE_O_waiting <= RAW_WE_O;
	       request_out_waiting[0] <= raw_request_wanted;

	       if (request_out_waiting[0]) begin
		  ADR_O_waiting <= RAW_ADR_O >> 1;
		  DAT_O_waiting <= RAW_DAT_O;
		  request_out_waiting[1] <= raw_request_wanted;
	       end else begin
		  ADR_O_waiting <= (RAW_ADR_O >> 1) + 1;
		  DAT_O_waiting <= {16'bx, RAW_DAT_O[31:16]};
		  request_out_waiting[1] <= 0;
	       end
	    end // else: !if(request_out_waiting[1])
	 end else if (!request_out_waiting[0]) begin // if (wr_request_happens)
	    ADR_O_waiting <= RAW_ADR_O >> 1;
	    WE_O_waiting <= RAW_WE_O;
	    DAT_O_waiting <= RAW_DAT_O;
	    request_out_waiting <= {2{raw_request_wanted}};
	 end
      end // else: !if(RST_I)
   end // always @ (posedge CLK_I)

   /* WRAPPED -> RAW */
   wire 	      wrapped_request_completes;
   assign wrapped_request_completes = WRAPPED_CYC_O && WRAPPED_ACK_I;

   reg [15:0] 	      DAT_I_waiting;
   reg 		      DAT_I_received;

   assign RAW_ACK_I = WRAPPED_ACK_I && DAT_I_received;
   assign RAW_ERR_I = 0; /* We'll start using it soon */
   assign RAW_DAT_I = {WRAPPED_DAT_I, DAT_I_waiting};
   assign RAW_STALL_I = !can_accept_request;

   always @ (posedge CLK_I) begin
      if (WRAPPED_ACK_I)
	DAT_I_waiting <= WRAPPED_DAT_I;

      if (RST_I)
	DAT_I_received <= 0;
      else if (wrapped_request_completes)
	DAT_I_received <= !DAT_I_received;
   end

`ifdef SIMULATION
   /* avoid undefined values */
   initial begin
      request_out_waiting <= 0;
      DAT_I_waiting <= 0;
   end
`endif
endmodule // interface_wrapper