1515// / 4. Reads boot address from soc_ctrl, jumps there with jalr zero (ra = &_eoc)
1616// / 5. On main() return: _eoc packs retval, writes CORESTATUS, halts
1717// / Trap handler dispatches to SRAM function pointer table at 0x1000_0000.
18- // / Source: bootrom.S (regenerate with: make -C rtl/bootrom)
18+ // / Source: bootrom.S
1919module bootrom # (
2020 // / The OBI configuration for all ports.
2121 parameter obi_pkg :: obi_cfg_t ObiCfg = obi_pkg :: ObiDefaultConfig,
@@ -30,108 +30,106 @@ module bootrom #(
3030 output obi_rsp_t obi_rsp_o
3131);
3232
33- // ---------------------------------------------------------------------------------------------
34- // Bootrom devided into blocks per contigous label
35- // ---------------------------------------------------------------------------------------------
36- // Contiguous block starting at 0x02000000: _start
37- localparam int unsigned StartRomWords = 28 ;
38- localparam logic [31 : 0 ] StartRom [StartRomWords] = '{
39- // <_start>
40- 32'h00800293 , // 0x02000000: addi x5,x0,8
41- 32'h30429073 , // 0x02000004: csrrw x0,mie,x5
42- 32'h10500073 , // 0x02000008: wfi
43- 32'h020402B7 , // 0x0200000C: lui x5,0x2040
44- 32'h0002A023 , // 0x02000010: sw x0,0(x5) # 2040000 <__global_pointer$+0x3e4d0>
45- 32'h30401073 , // 0x02000014: csrrw x0,mie,x0
46- 32'h00000093 , // 0x02000018: addi x1,x0,0
47- 32'h00000193 , // 0x0200001C: addi x3,x0,0
48- 32'h00000213 , // 0x02000020: addi x4,x0,0
49- 32'h00000293 , // 0x02000024: addi x5,x0,0
50- 32'h00000313 , // 0x02000028: addi x6,x0,0
51- 32'h00000393 , // 0x0200002C: addi x7,x0,0
52- 32'h00000413 , // 0x02000030: addi x8,x0,0
53- 32'h00000493 , // 0x02000034: addi x9,x0,0
54- 32'h00000513 , // 0x02000038: addi x10,x0,0
55- 32'h00000593 , // 0x0200003C: addi x11,x0,0
56- 32'h00000613 , // 0x02000040: addi x12,x0,0
57- 32'h00000693 , // 0x02000044: addi x13,x0,0
58- 32'h00000713 , // 0x02000048: addi x14,x0,0
59- 32'h00000793 , // 0x0200004C: addi x15,x0,0
60- 32'h00000297 , // 0x02000050: auipc x5,0x0
61- 32'h1B028293 , // 0x02000054: addi x5,x5,432 # 2000200 <_trap_handler_wrapper>
62- 32'h30529073 , // 0x02000058: csrrw x0,mtvec,x5
63- 32'h030002B7 , // 0x0200005C: lui x5,0x3000
64- 32'h0002A283 , // 0x02000060: lw x5,0(x5) # 3000000 <__global_pointer$+0xffe4d0>
65- 32'h00000097 , // 0x02000064: auipc x1,0x0
66- 32'h09C08093 , // 0x02000068: addi x1,x1,156 # 2000100 <_eoc>
67- 32'h00028067 // 0x0200006C: jalr x0,0(x5)
68- } ;
69-
70- // Contiguous block starting at 0x02000100: _eoc
71- localparam int unsigned EocRomWords = 5 ;
72- localparam logic [31 : 0 ] EocRomData [EocRomWords] = '{
73- // <_eoc>
74- 32'h00151293 , // 0x02000100: slli x5,x10,0x1x00010413
75- 32'h0012E293 , // 0x02000104: ori x5,x5,1
76- 32'h03000337 , // 0x02000108: lui x6,0x3000
77- 32'h00532423 , // 0x0200010C: sw x5,8(x6) # 3000008 <__global_pointer$+0xffe4d8>
78- 32'h10500073 // 0x02000110: wfi
79- } ;
80-
81- // Contiguous block starting at 0x02000200: _trap_handler_wrapper
82- localparam int unsigned TrapHandlerRomWords = 23 ;
83- localparam logic [31 : 0 ] TrapHandlerRomData [TrapHandlerRomWords] = '{
84- // <_trap_handler_wrapper>
85- 32'hFB010113 , // 0x02000200: addi x2,x2,-80
86- 32'h04112423 , // 0x02000204: sw x1,72(x2)
87- 32'h04512023 , // 0x02000208: sw x5,64(x2)
88- 32'h02612C23 , // 0x0200020C: sw x6,56(x2)
89- 32'h02712823 , // 0x02000210: sw x7,48(x2)
90- 32'h02A12423 , // 0x02000214: sw x10,40(x2)
91- 32'h02B12023 , // 0x02000218: sw x11,32(x2)
92- 32'h00C12C23 , // 0x0200021C: sw x12,24(x2)
93- 32'h00D12823 , // 0x02000220: sw x13,16(x2)
94- 32'h00E12423 , // 0x02000224: sw x14,8(x2)
95- 32'h00F12023 , // 0x02000228: sw x15,0(x2)
96- 32'h34202573 , // 0x0200022C: csrrs x10,mcause,x0
97- 32'h00054A63 , // 0x02000230: blt x10,x0,2000244 <_handle_interrupt>
98- 32'h100002B7 , // 0x02000234: lui x5,0x10000
99- 32'h0042A283 , // 0x02000238: lw x5,4(x5) # 10000004 <__global_pointer$+0xdffe4d4>
100- 32'h000280E7 , // 0x0200023C: jalr x1,0(x5)
101- 32'h0C00006F , // 0x02000240: jal x0,2000300 <_trap_exit>
102- // <_handle_interrupt>
103- 32'h00151513 , // 0x02000244: slli x10,x10,0x1
104- 32'h00155513 , // 0x02000248: srli x10,x10,0x1
105- 32'h100002B7 , // 0x0200024C: lui x5,0x10000
106- 32'h0082A283 , // 0x02000250: lw x5,8(x5) # 10000008 <__global_pointer$+0xdffe4d8>
107- 32'h000280E7 , // 0x02000254: jalr x1,0(x5)
108- 32'h0A80006F // 0x02000258: jal x0,2000300 <_trap_exit>
109- } ;
110-
111- // Contiguous block starting at 0x02000300: _trap_exit
112- localparam int unsigned TrapExitRomWords = 12 ;
113- localparam logic [31 : 0 ] TrapExitRomData [TrapExitRomWords] = '{
114- // <_trap_exit>
115- 32'h04812083 , // 0x02000300: lw x1,72(x2)
116- 32'h04012283 , // 0x02000304: lw x5,64(x2)
117- 32'h03812303 , // 0x02000308: lw x6,56(x2)
118- 32'h03012383 , // 0x0200030C: lw x7,48(x2)
119- 32'h02812503 , // 0x02000310: lw x10,40(x2)
120- 32'h02012583 , // 0x02000314: lw x11,32(x2)
121- 32'h01812603 , // 0x02000318: lw x12,24(x2)
122- 32'h01012683 , // 0x0200031C: lw x13,16(x2)
123- 32'h00812703 , // 0x02000320: lw x14,8(x2)
124- 32'h00012783 , // 0x02000324: lw x15,0(x2)
125- 32'h05010113 , // 0x02000328: addi x2,x2,80
126- 32'h30200073 // 0x0200032C: mret
127- } ;
128-
129-
130-
131- // --------------------------------------------------------------------------
132- // Handle OBI requests
133- // --------------------------------------------------------------------------
134- localparam int unsigned WordAddressWidth = 10 ; // 12bit byte address
33+ // ---------------------------------------------------------------------------------------------
34+ // Bootrom divided into blocks per contiguous label
35+ // ---------------------------------------------------------------------------------------------
36+ // Contiguous block starting at 0x02000000: _start
37+ localparam int unsigned StartRomWords = 28 ;
38+ localparam logic [31 : 0 ] StartRom [StartRomWords] = '{
39+ // <_start>
40+ 32'h00800293 , // 0x02000000: li t0,8
41+ 32'h30429073 , // 0x02000004: csrw mie,t0
42+ 32'h10500073 , // 0x02000008: wfi
43+ 32'h020402B7 , // 0x0200000C: lui t0,0x2040
44+ 32'h0002A023 , // 0x02000010: sw zero,0(t0) # 2040000 <__global_pointer$+0x3e4d0>
45+ 32'h30401073 , // 0x02000014: csrw mie,zero
46+ 32'h00000093 , // 0x02000018: li ra,0
47+ 32'h00000193 , // 0x0200001C: li gp,0
48+ 32'h00000213 , // 0x02000020: li tp,0
49+ 32'h00000293 , // 0x02000024: li t0,0
50+ 32'h00000313 , // 0x02000028: li t1,0
51+ 32'h00000393 , // 0x0200002C: li t2,0
52+ 32'h00000413 , // 0x02000030: li s0,0
53+ 32'h00000493 , // 0x02000034: li s1,0
54+ 32'h00000513 , // 0x02000038: li a0,0
55+ 32'h00000593 , // 0x0200003C: li a1,0
56+ 32'h00000613 , // 0x02000040: li a2,0
57+ 32'h00000693 , // 0x02000044: li a3,0
58+ 32'h00000713 , // 0x02000048: li a4,0
59+ 32'h00000793 , // 0x0200004C: li a5,0
60+ 32'h00000297 , // 0x02000050: auipc t0,0x0
61+ 32'h1B028293 , // 0x02000054: addi t0,t0,432 # 2000200 <_trap_handler_wrapper>
62+ 32'h30529073 , // 0x02000058: csrw mtvec,t0
63+ 32'h030002B7 , // 0x0200005C: lui t0,0x3000
64+ 32'h0002A283 , // 0x02000060: lw t0,0(t0) # 3000000 <__global_pointer$+0xffe4d0>
65+ 32'h00000097 , // 0x02000064: auipc ra,0x0
66+ 32'h09C08093 , // 0x02000068: addi ra,ra,156 # 2000100 <_eoc>
67+ 32'h00028067 // 0x0200006C: jr t0
68+ } ;
69+
70+ // Contiguous block starting at 0x02000100: _eoc
71+ localparam int unsigned EocRomWords = 5 ;
72+ localparam logic [31 : 0 ] EocRomData [EocRomWords] = '{
73+ // <_eoc>
74+ 32'h00151293 , // 0x02000100: slli t0,a0,0x1
75+ 32'h0012E293 , // 0x02000104: ori t0,t0,1
76+ 32'h03000337 , // 0x02000108: lui t1,0x3000
77+ 32'h00532423 , // 0x0200010C: sw t0,8(t1) # 3000008 <__global_pointer$+0xffe4d8>
78+ 32'h10500073 // 0x02000110: wfi
79+ } ;
80+
81+ // Contiguous block starting at 0x02000200: _trap_handler_wrapper
82+ localparam int unsigned TrapHandlerRomWords = 23 ;
83+ localparam logic [31 : 0 ] TrapHandlerRomData [TrapHandlerRomWords] = '{
84+ // <_trap_handler_wrapper>
85+ 32'hFB010113 , // 0x02000200: addi sp,sp,-80
86+ 32'h04112423 , // 0x02000204: sw ra,72(sp)
87+ 32'h04512023 , // 0x02000208: sw t0,64(sp)
88+ 32'h02612C23 , // 0x0200020C: sw t1,56(sp)
89+ 32'h02712823 , // 0x02000210: sw t2,48(sp)
90+ 32'h02A12423 , // 0x02000214: sw a0,40(sp)
91+ 32'h02B12023 , // 0x02000218: sw a1,32(sp)
92+ 32'h00C12C23 , // 0x0200021C: sw a2,24(sp)
93+ 32'h00D12823 , // 0x02000220: sw a3,16(sp)
94+ 32'h00E12423 , // 0x02000224: sw a4,8(sp)
95+ 32'h00F12023 , // 0x02000228: sw a5,0(sp)
96+ 32'h34202573 , // 0x0200022C: csrr a0,mcause
97+ 32'h00054A63 , // 0x02000230: bltz a0,2000244 <_handle_interrupt>
98+ 32'h100002B7 , // 0x02000234: lui t0,0x10000
99+ 32'h0042A283 , // 0x02000238: lw t0,4(t0) # 10000004 <__global_pointer$+0xdffe4d4>
100+ 32'h000280E7 , // 0x0200023C: jalr t0
101+ 32'h0C00006F , // 0x02000240: j 2000300 <_trap_exit>
102+ 32'h00151513 , // 0x02000244: slli a0,a0,0x1
103+ 32'h00155513 , // 0x02000248: srli a0,a0,0x1
104+ 32'h100002B7 , // 0x0200024C: lui t0,0x10000
105+ 32'h0082A283 , // 0x02000250: lw t0,8(t0) # 10000008 <__global_pointer$+0xdffe4d8>
106+ 32'h000280E7 , // 0x02000254: jalr t0
107+ 32'h0A80006F // 0x02000258: j 2000300 <_trap_exit>
108+ } ;
109+
110+ // Contiguous block starting at 0x02000300: _trap_exit
111+ localparam int unsigned TrapExitRomWords = 12 ;
112+ localparam logic [31 : 0 ] TrapExitRomData [TrapExitRomWords] = '{
113+ // <_trap_exit>
114+ 32'h04812083 , // 0x02000300: lw ra,72(sp)
115+ 32'h04012283 , // 0x02000304: lw t0,64(sp)
116+ 32'h03812303 , // 0x02000308: lw t1,56(sp)
117+ 32'h03012383 , // 0x0200030C: lw t2,48(sp)
118+ 32'h02812503 , // 0x02000310: lw a0,40(sp)
119+ 32'h02012583 , // 0x02000314: lw a1,32(sp)
120+ 32'h01812603 , // 0x02000318: lw a2,24(sp)
121+ 32'h01012683 , // 0x0200031C: lw a3,16(sp)
122+ 32'h00812703 , // 0x02000320: lw a4,8(sp)
123+ 32'h00012783 , // 0x02000324: lw a5,0(sp)
124+ 32'h05010113 , // 0x02000328: addi sp,sp,80
125+ 32'h30200073 // 0x0200032C: mret
126+ } ;
127+
128+
129+ // --------------------------------------------------------------------------
130+ // Handle OBI requests
131+ // --------------------------------------------------------------------------
132+ localparam int unsigned WordAddressWidth = 10 ; // 12-bit byte address -> 10-bit word address
135133
136134 logic we_d, we_q;
137135 logic req_d, req_q;
@@ -149,59 +147,59 @@ module bootrom #(
149147 `FF (id_q, id_d, '0 , clk_i, rst_ni)
150148 `FF (word_addr_q, word_addr_d, '0 , clk_i, rst_ni)
151149
152- // --------------------------------------------------------------------------
153- // Mask-based ROM decode:
154- // - upper 4 bits of the *word address* select the ROM
155- // - lower 6 bits select the word within that block
156- // --------------------------------------------------------------------------
157- logic rom_req;
158- logic [ 3 : 0 ] rom_select;
159- logic [ 5 : 0 ] rom_idx, rom_size;
160- logic rom_error;
161- logic [31 : 0 ] rom_rdata;
162-
163- assign rom_req = req_q && ! we_d ;
164- assign rom_select = word_addr_q[WordAddressWidth- 1 - : 4 ];
165- assign rom_idx = word_addr_q[5 : 0 ];
150+ // --------------------------------------------------------------------------
151+ // Mask-based ROM decode:
152+ // - upper 4 bits of the *word address* select the ROM block
153+ // - lower 6 bits select the word within that block
154+ // --------------------------------------------------------------------------
155+ logic rom_req;
156+ logic [ 3 : 0 ] rom_select;
157+ logic [ 5 : 0 ] rom_idx, rom_size;
158+ logic rom_error;
159+ logic [31 : 0 ] rom_rdata;
160+
161+ assign rom_req = req_q && ! we_q ;
162+ assign rom_select = word_addr_q[WordAddressWidth- 1 - : 4 ];
163+ assign rom_idx = word_addr_q[5 : 0 ];
166164
167165 always_comb begin
168166 rom_rdata = 32'h0000_0000 ;
169167 rom_error = 1'b1 ;
170168
171- case (rom_select)
172- 4'b0000 : rom_size = StartRomWords;
173- 4'b0001 : rom_size = EocRomWords;
174- 4'b0010 : rom_size = TrapHandlerRomWords;
175- 4'b0011 : rom_size = TrapExitRomWords;
176- default : rom_size = 8 'h00 ;
177- endcase
178-
179- rom_error = (rom_idx >= rom_size);
180-
181- if (! rom_error && rom_req) begin
182- case (rom_select)
183- 4'b0000 : rom_rdata = StartRom[rom_idx];
184- 4'b0001 : rom_rdata = EocRomData[rom_idx];
185- 4'b0010 : rom_rdata = TrapHandlerRomData[rom_idx];
186- 4'b0011 : rom_rdata = TrapExitRomData[rom_idx];
187- default : rom_rdata = 32'h0000_0000 ;
188- endcase
189- end
190- end
191-
192- always_comb begin
193- obi_rsp_o = '0 ;
194- obi_rsp_o.gnt = 1'b1 ; // always grant
195- obi_rsp_o.rvalid = req_q;
196- obi_rsp_o.r.rid = id_q;
197- if (we_q) begin
198- // write request
199- obi_rsp_o.r.rdata = 32'hBADCAB1E ;
200- obi_rsp_o.r.err = 1'b1 ;
201- end else begin
202- obi_rsp_o.r.rdata = rom_rdata;
203- obi_rsp_o.r.err = 1'b0 ;
204- end
205- end
169+ case (rom_select)
170+ 4'b0000 : rom_size = StartRomWords;
171+ 4'b0001 : rom_size = EocRomWords;
172+ 4'b0010 : rom_size = TrapHandlerRomWords;
173+ 4'b0011 : rom_size = TrapExitRomWords;
174+ default : rom_size = 6 'h00 ;
175+ endcase
176+
177+ rom_error = (rom_idx >= rom_size);
178+
179+ if (! rom_error && rom_req) begin
180+ case (rom_select)
181+ 4'b0000 : rom_rdata = StartRom[rom_idx];
182+ 4'b0001 : rom_rdata = EocRomData[rom_idx];
183+ 4'b0010 : rom_rdata = TrapHandlerRomData[rom_idx];
184+ 4'b0011 : rom_rdata = TrapExitRomData[rom_idx];
185+ default : rom_rdata = 32'h0000_0000 ;
186+ endcase
187+ end
188+ end
189+
190+ always_comb begin
191+ obi_rsp_o = '0 ;
192+ obi_rsp_o.gnt = 1'b1 ; // always grant
193+ obi_rsp_o.rvalid = req_q;
194+ obi_rsp_o.r.rid = id_q;
195+ if (we_q) begin
196+ // write request
197+ obi_rsp_o.r.rdata = 32'hBADCAB1E ;
198+ obi_rsp_o.r.err = 1'b1 ;
199+ end else begin
200+ obi_rsp_o.r.rdata = rom_rdata;
201+ obi_rsp_o.r.err = rom_error ;
202+ end
203+ end
206204
207205endmodule
0 commit comments