memory: preliminary, regfile: more read port, decode: more correct
[firearm.git] / Memory.v
1 `include "ARM_Constants.v"
2
3 module Memory(
4         input clk,
5         input Nrst,
6         input [31:0] pc,
7         input [31:0] insn,
8         input [31:0] base,
9         input [31:0] offset,
10
11         /* bus interface */
12         output reg [31:0] busaddr,
13         output reg rd_req,
14         output reg wr_req,
15         input rw_wait,
16         output reg [31:0] wr_data,
17         input [31:0] rd_data,
18
19         /* regfile interface */
20         output reg [3:0] st_read,
21         input [31:0] st_data,
22
23         /* writeback to base */
24         output reg writeback,
25         output reg [3:0] regsel,
26         output reg [31:0] regdata,
27
28         /* pc stuff */
29         output reg [31:0] outpc,
30         output reg [31:0] newpc,
31
32         /* stall */
33         output outstall,
34         output reg outbubble,
35         output reg flush
36 );
37
38         reg [31:0] addr, raddr;
39         reg notdone = 1'b0;
40         reg inc_next = 1'b0;
41         wire [31:0] align_s1, align_s2, align_rddata;
42         assign outstall = rw_wait | notdone;
43
44         always @(*)
45         begin
46                 addr = 32'hxxxxxxxx;
47                 raddr = 32'hxxxxxxxx;
48                 rd_req = 1'b0;
49                 wr_req = 1'b0;
50                 wr_data = 32'hxxxxxxxx;
51                 busaddr = 32'hxxxxxxxx;
52                 outstall = 1'b0;
53                 casez(insn)
54                 `DECODE_LDRSTR_UNDEFINED: begin end
55                 `DECODE_LDRSTR: begin
56                         addr = insn[23] ? base + offset : base - offset; /* up/down select */
57                         raddr = insn[24] ? base : addr;
58                         busaddr = {raddr[31:2], 2'b0}; /* pre/post increment */
59                         rd_req = insn[20];
60                         wr_req = ~insn[20];
61                         if(!insn[20]) begin /* store */
62                                 st_read = insn[15:12];
63                                 wr_data = insn[22] ? {4{st_data[7:0]}} : st_data;
64                         end
65                         else if(insn[15:12] == 4'hF)
66                                 flush = 1'b1;
67                 end
68                 `DECODE_LDMSTM: begin
69                 end
70                 default: begin end
71                 endcase
72         end
73
74         assign align_s1 = raddr[1] ? {rd_data[15:0], rd_data[31:16]} : rd_data;
75         assign align_s2 = raddr[0] ? {align_s1[7:0], align_s1[31:8]} : align_s1;
76         assign align_rddata = insn[22] ? {24'b0, align_s2[7:0]} : align_s2;
77
78         always @(posedge clk)
79         begin
80                 outpc <= pc;
81                 outbubble <= rw_wait;
82                 casez(insn)
83                 `DECODE_LDRSTR_UNDEFINED: begin
84                         writeback <= 1'b0;
85                         regsel <= 4'hx;
86                         regdata <= 32'hxxxxxxxx;
87                         notdone <= 1'b0;
88                 end
89                 `DECODE_LDRSTR: begin
90                         if(insn[20] && !inc_next) begin /* load - delegate regfile write to writeback stage */
91                                 if(insn[15:12] == 4'hF) begin
92                                         newpc <= align_rddata;
93                                 end
94                                 else begin
95                                         writeback <= 1'b1;
96                                         regsel <= insn[15:12];
97                                         regdata <= align_rddata;
98                                 end
99                                 inc_next <= 1'b1;
100                         end
101                         else if(insn[21]) begin /* write back */
102                                 writeback <= 1'b1;
103                                 regsel <= insn[19:16];
104                                 regdata <= addr;
105                                 inc_next <= 1'b0;
106                         end else begin
107                                 writeback <= 1'b0;
108                                 inc_next <= 1'b0;
109                                 regsel <= 4'hx;
110                                 regdata <= 32'hxxxxxxxx;
111                         end
112                         notdone <= rw_wait & insn[20] & insn[21];
113                 end
114                 `DECODE_LDMSTM: begin
115                 end
116                 default: begin
117                         writeback <= 1'b0;
118                         regsel <= 4'hx;
119                         regdata <= 32'hxxxxxxxx;
120                         notdone <= 1'b0;
121                 end
122                 endcase
123         end
124
125 endmodule
This page took 0.023949 seconds and 4 git commands to generate.