memory instructions
This commit is contained in:
		
							parent
							
								
									ee7ff194c4
								
							
						
					
					
						commit
						95b2be3ab7
					
				| @ -85,6 +85,7 @@ module hart( | |||||||
|     reg [31:0] t_e_result; |     reg [31:0] t_e_result; | ||||||
|     reg        t_e_branch; |     reg        t_e_branch; | ||||||
|     reg [31:0] t_e_address; |     reg [31:0] t_e_address; | ||||||
|  |     reg [31:0] t_e_tmp1; | ||||||
| 
 | 
 | ||||||
|     always begin |     always begin | ||||||
|         // instruction fetch
 |         // instruction fetch
 | ||||||
| @ -203,8 +204,57 @@ module hart( | |||||||
|                     t_e_branch  = 1; |                     t_e_branch  = 1; | ||||||
|                 end |                 end | ||||||
|             end |             end | ||||||
|             { `INS_LOAD,   `F3_DONT_CARE,   `F7_DONT_CARE }: $error("NOT IMPLEMENTED"); |             { `INS_LOAD,   `F3_DONT_CARE,   `F7_DONT_CARE }: begin | ||||||
|             { `INS_STORE,  `F3_DONT_CARE,   `F7_DONT_CARE }: $error("NOT IMPLEMENTED"); |                 t_e_address = t_d_imm + t_r_a; | ||||||
|  |                 pmmu_addr = t_e_address; | ||||||
|  |                 pmmu_rd = 1; | ||||||
|  | 
 | ||||||
|  |                 #1; | ||||||
|  |                 pmmu_rd = 0; | ||||||
|  |                 case (t_d_f3[1:0]) | ||||||
|  |                     0: t_e_result = (pmmu_datar >> (8 * (t_e_address & 3))) & 255; | ||||||
|  |                     1: begin | ||||||
|  |                         if (t_e_address[0] != 0) $error("UNALIGNED READ %08x", t_e_address); | ||||||
|  |                         t_e_result = (pmmu_datar >> (8 * (t_e_address & 2))) & 'hffff; | ||||||
|  |                     end | ||||||
|  |                     2: begin | ||||||
|  |                         if (t_e_address[1:0] != 0) $error("UNALIGNED READ %08x", t_e_address); | ||||||
|  |                         t_e_result = pmmu_datar; | ||||||
|  |                     end | ||||||
|  |                     3: $error("INVALID INSTRUCTION"); | ||||||
|  |                 endcase | ||||||
|  | 
 | ||||||
|  |                 case (t_d_f3) | ||||||
|  |                     1,2,3,4:; | ||||||
|  |                     4: t_e_result = { {24{t_e_result[7]}}, t_e_result[7:0] }; | ||||||
|  |                     5: t_e_result = { {16{t_e_result[16]}}, t_e_result[15:0] }; | ||||||
|  |                     6, 7: $error("INVALID INSTRUCTION"); | ||||||
|  |                 endcase | ||||||
|  |             end | ||||||
|  |             { `INS_STORE,  `F3_DONT_CARE,   `F7_DONT_CARE }: begin | ||||||
|  |                 t_e_address = t_d_imm + t_r_a; | ||||||
|  |                 pmmu_addr = t_e_address; | ||||||
|  |                 pmmu_rd = 1; | ||||||
|  | 
 | ||||||
|  |                 #1; | ||||||
|  |                 case (t_d_f3) | ||||||
|  |                     0: begin | ||||||
|  |                         pmmu_dataw = pmmu_datar & ~('hff << (8 * t_e_address[1:0])) | (t_r_b & 'hff) << (8 * t_e_address[1:0]); | ||||||
|  |                     end | ||||||
|  |                     1: begin | ||||||
|  |                         if (t_e_address[0] != 0) $error("UNALIGNED STORE %08x", t_e_address); | ||||||
|  |                         pmmu_dataw = pmmu_datar & ~('hffff << (8 * t_e_address[1:0])) | (t_r_b & 'hffff) << (8 * t_e_address[1:0]); | ||||||
|  |                     end | ||||||
|  |                     2: begin | ||||||
|  |                         if (t_e_address[1:0] != 0) $error("UNALIGNED STORE %08x", t_e_address); | ||||||
|  |                         pmmu_dataw = t_r_b; | ||||||
|  |                     end | ||||||
|  |                     3, 4, 5, 6, 7: $error("INVALID INSTRUCTION"); | ||||||
|  |                 endcase | ||||||
|  | 
 | ||||||
|  |                 pmmu_wr = 1; | ||||||
|  |                 pmmu_rd = 0; | ||||||
|  |             end | ||||||
|             { `INS_IMMOP,  `INS_ALUOP_ADD,  `F7_DONT_CARE }: begin |             { `INS_IMMOP,  `INS_ALUOP_ADD,  `F7_DONT_CARE }: begin | ||||||
|                 t_e_result = $signed(t_r_a) + $signed(t_d_imm); |                 t_e_result = $signed(t_r_a) + $signed(t_d_imm); | ||||||
|             end |             end | ||||||
| @ -267,8 +317,8 @@ module hart( | |||||||
|             default: $error("INVALID INSTRUCTION");  |             default: $error("INVALID INSTRUCTION");  | ||||||
|         endcase |         endcase | ||||||
| 
 | 
 | ||||||
|         // write back
 |         // write back (ignore the delay, its not important)
 | ||||||
|         @(posedge clk); |         @(posedge clk); #1; | ||||||
|         $display("== WRITE REGISTERS =="); |         $display("== WRITE REGISTERS =="); | ||||||
| 
 | 
 | ||||||
|         case (t_d_op) |         case (t_d_op) | ||||||
| @ -280,5 +330,11 @@ module hart( | |||||||
| 
 | 
 | ||||||
|         // finish up
 |         // finish up
 | ||||||
|         reg_pc = t_e_branch ? t_e_address : reg_pc + 4; |         reg_pc = t_e_branch ? t_e_address : reg_pc + 4; | ||||||
|  | 
 | ||||||
|  |         // shhhh... you dont see this...
 | ||||||
|  |         pmmu_rd    = 0; | ||||||
|  |         pmmu_wr    = 0; | ||||||
|  |         pmmu_addr  = 0; | ||||||
|  |         pmmu_dataw = 0; | ||||||
|     end |     end | ||||||
| endmodule | endmodule | ||||||
| @ -5,7 +5,10 @@ module pmmu( | |||||||
|     addr, datar, dataw, |     addr, datar, dataw, | ||||||
| 
 | 
 | ||||||
|     rom_rd, |     rom_rd, | ||||||
|     rom_addr, rom_datar |     rom_addr, rom_datar, | ||||||
|  | 
 | ||||||
|  |     ram_rd, ram_wr, | ||||||
|  |     ram_addr, ram_datar, ram_dataw | ||||||
| ); | ); | ||||||
|     // INPUT SHIT
 |     // INPUT SHIT
 | ||||||
|     input             clk; |     input             clk; | ||||||
| @ -20,16 +23,39 @@ module pmmu( | |||||||
|     output reg [31:0] rom_addr; |     output reg [31:0] rom_addr; | ||||||
|     input  reg [31:0] rom_datar; |     input  reg [31:0] rom_datar; | ||||||
| 
 | 
 | ||||||
|  |     // RAM
 | ||||||
|  |     output reg        ram_rd; | ||||||
|  |     output reg        ram_wr; | ||||||
|  |     output reg [31:0] ram_addr; | ||||||
|  |     output reg [31:0] ram_dataw; | ||||||
|  |     input  reg [31:0] ram_datar; | ||||||
|  | 
 | ||||||
|     always @(posedge clk) begin |     always @(posedge clk) begin | ||||||
|         rom_rd = 0; |         rom_rd = 0; | ||||||
|  |         ram_rd = 0; | ||||||
|  |         ram_wr = 0; | ||||||
| 
 | 
 | ||||||
|         if ((addr == 0 || addr > 0) && addr < 'h100) begin |         if ((addr == 0 || addr > 0) && addr < 'h1000) begin | ||||||
|             rom_addr  = addr >> 2; |             rom_addr  = addr >> 2; | ||||||
|             rom_rd    = rd; |             rom_rd    = rd; | ||||||
|             #1; // wait for it to finish
 | 
 | ||||||
|  |             #1; | ||||||
|             if (rd) datar = rom_datar; |             if (rd) datar = rom_datar; | ||||||
|  | 
 | ||||||
|  |             rom_rd = 0; | ||||||
|  |         end else if ((addr == 'h100000 || addr > 'h100000) && addr < 'h101000) begin | ||||||
|  |             ram_addr = addr >> 2; | ||||||
|  |             ram_rd   = rd; | ||||||
|  |             ram_wr   = wr; | ||||||
|  |             if (wr) ram_dataw = dataw; | ||||||
|  |              | ||||||
|  |             #1; | ||||||
|  |             if (rd) datar = ram_datar; | ||||||
|  | 
 | ||||||
|  |             ram_wr = 0; | ||||||
|  |             ram_rd = 0; | ||||||
|         end else begin |         end else begin | ||||||
|             $error("THIS IS BAD"); |             $error("INVALID MEMORY ACCESS %08x", addr); | ||||||
|         end |         end | ||||||
|     end |     end | ||||||
| endmodule | endmodule | ||||||
							
								
								
									
										25
									
								
								board/parts/ram.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								board/parts/ram.sv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | |||||||
|  | module ram( | ||||||
|  |     input            clk, | ||||||
|  |     input  reg       rd, | ||||||
|  |     input  reg       wr, | ||||||
|  |     input  reg[31:0] addr, | ||||||
|  |     output reg[31:0] datar, | ||||||
|  |     input  reg[31:0] dataw | ||||||
|  | ); | ||||||
|  |     parameter SIZE = 'h1000; | ||||||
|  | 
 | ||||||
|  |     reg [31:0] data[0 : SIZE - 1]; | ||||||
|  | 
 | ||||||
|  |     always @(posedge clk) begin | ||||||
|  |         // $display("RAM: %c%c", wr ? "W" : "-", rd ? "R" : "-");
 | ||||||
|  |          | ||||||
|  |         if (wr) begin | ||||||
|  |             $display("RAM: [%08x] <= %d", addr << 2, dataw); | ||||||
|  |             data[addr] = dataw; | ||||||
|  |         end | ||||||
|  |         if (rd) begin | ||||||
|  |             $display("RAM: [%08x] => %d", addr << 2, data[addr]); | ||||||
|  |             datar = data[addr]; | ||||||
|  |         end else datar = 0; | ||||||
|  |     end | ||||||
|  | endmodule | ||||||
| @ -1,6 +1,7 @@ | |||||||
| `include "parts/hart.sv"; | `include "parts/hart.sv"; | ||||||
| `include "parts/pmmu.sv"; | `include "parts/pmmu.sv"; | ||||||
| `include "parts/rom.sv"; | `include "parts/rom.sv"; | ||||||
|  | `include "parts/ram.sv"; | ||||||
| 
 | 
 | ||||||
| module system(); | module system(); | ||||||
|     reg clock = 0; // its the clock
 |     reg clock = 0; // its the clock
 | ||||||
| @ -13,12 +14,17 @@ module system(); | |||||||
|     reg        wire_rom_rd; |     reg        wire_rom_rd; | ||||||
|     reg [31:0] wire_rom_addr; |     reg [31:0] wire_rom_addr; | ||||||
|     reg [31:0] wire_rom_datar; |     reg [31:0] wire_rom_datar; | ||||||
| 
 |     reg        wire_ram_rd; | ||||||
|  |     reg        wire_ram_wr; | ||||||
|  |     reg [31:0] wire_ram_addr; | ||||||
|  |     reg [31:0] wire_ram_datar; | ||||||
|  |     reg [31:0] wire_ram_dataw; | ||||||
| 
 | 
 | ||||||
|     hart core(clock, wire_rd, wire_wr, wire_addr, wire_datar, wire_dataw); // cpu thing
 |     hart core(clock, wire_rd, wire_wr, wire_addr, wire_datar, wire_dataw); // cpu thing
 | ||||||
|      |      | ||||||
|     rom#(.FILE("./build/kernel.mem")) rom(clock, wire_rom_rd, wire_rom_addr, wire_rom_datar); |     rom#(.FILE("./build/kernel.mem")) rom(clock, wire_rom_rd, wire_rom_addr, wire_rom_datar); | ||||||
|     pmmu pmmu(clock, wire_rd, wire_wr, wire_addr, wire_datar, wire_dataw, wire_rom_rd, wire_rom_addr, wire_rom_datar); |     ram#(.SIZE('h1000)) ram(clock, wire_ram_rd, wire_ram_wr, wire_ram_addr, wire_ram_datar, wire_ram_dataw); | ||||||
|  |     pmmu pmmu(clock, wire_rd, wire_wr, wire_addr, wire_datar, wire_dataw, wire_rom_rd, wire_rom_addr, wire_rom_datar, wire_ram_rd, wire_ram_wr, wire_ram_addr, wire_ram_datar, wire_ram_dataw); | ||||||
| 
 | 
 | ||||||
|     // run the clock
 |     // run the clock
 | ||||||
|     always #5 clock = ~clock; |     always #5 clock = ~clock; | ||||||
|  | |||||||
							
								
								
									
										3
									
								
								makefile
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								makefile
									
									
									
									
									
								
							| @ -6,7 +6,8 @@ VERILOG_SOURCES = \ | |||||||
| 	board/system.sv \
 | 	board/system.sv \
 | ||||||
| 	board/parts/hart.sv \
 | 	board/parts/hart.sv \
 | ||||||
| 	board/parts/pmmu.sv \
 | 	board/parts/pmmu.sv \
 | ||||||
| 	board/parts/rom.sv  | 	board/parts/rom.sv \
 | ||||||
|  | 	board/parts/ram.sv  | ||||||
| 
 | 
 | ||||||
| KERNEL_SOURCES = \
 | KERNEL_SOURCES = \
 | ||||||
| 	os/kernel/boot.s | 	os/kernel/boot.s | ||||||
|  | |||||||
| @ -1,12 +1,23 @@ | |||||||
| _start:  | _start:  | ||||||
|     li  x1, 0 |     li  x1, 8      // ITERATION * 4 | ||||||
|     li  x2, 1 |     li  x2, 5 * 4 // MAX ITERATIONS * 4 | ||||||
|     li  x3, 0 |     li  x6, 0x100000 // MEM OFFSET | ||||||
|     li  x4, 0 | 
 | ||||||
|     li  x5, 32 |     li  x5, 1 | ||||||
|  |     sw  x5, 4(x6) | ||||||
| fib:  | fib:  | ||||||
|     add x3, x1, x2 |     add x3, x6, x1 | ||||||
|     mv  x1, x2 |     lw  x4, -4(x3) // get a | ||||||
|     mv  x2, x3 |     lw  x5, -8(x3) // get b | ||||||
|     add x4, x4, 1 |     add x4, x4, x5 // a = a + b | ||||||
|     bne x4, x5, fib |     sw  x4, (x3)   // store a to c | ||||||
|  | 
 | ||||||
|  |     // increment or stop | ||||||
|  |     add x1, x1, 4 | ||||||
|  |     bne x1, x2, fib | ||||||
|  | 
 | ||||||
|  |     li  x5, 12345678 | ||||||
|  |     sw  x5, (x6) | ||||||
|  |     li  x5, 0 | ||||||
|  |     lw  x5, (x6) | ||||||
|  |     mv  x6, x5 | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user