aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSnuffick <aleks.bae@gmail.com>2015-10-21 17:10:49 +0300
committerSnuffick <aleks.bae@gmail.com>2015-10-21 17:10:49 +0300
commit8ffeebb76b0ef25292741ea027f6e2d429949a12 (patch)
tree12ae8f5b55d91111566c0084e5da7ae533450a77
parent65dfded3a27aa84aa4ec21e755c17e48b3e56033 (diff)
downloadMIPSLabs-8ffeebb76b0ef25292741ea027f6e2d429949a12.zip
MIPSLabs-8ffeebb76b0ef25292741ea027f6e2d429949a12.tar.gz
MIPSLabs-8ffeebb76b0ef25292741ea027f6e2d429949a12.tar.bz2
Исправлено неверное поведение mips32 при доступе к адресному пространству секции кода.
-rw-r--r--hdl/dp_memory.v24
-rw-r--r--hdl/master_wb.v54
-rw-r--r--sw/test.asm10
3 files changed, 56 insertions, 32 deletions
diff --git a/hdl/dp_memory.v b/hdl/dp_memory.v
index dd5dff9..9db03c3 100644
--- a/hdl/dp_memory.v
+++ b/hdl/dp_memory.v
@@ -33,8 +33,15 @@ module bus_control #(
output wbm_stb_o
);
- wire i_bram_select;
+ wire i_bram_select;
+ wire d_bram_select;
+ wire [31:0] external_data;
+ wire external_data_wren;
+ wire external_data_rden;
+
+ wire done_please;
+
reg [31:0] memory[addr_low:addr_high];
initial begin
@@ -42,8 +49,15 @@ module bus_control #(
end
assign i_bram_select = (i_addr <= addr_high && i_addr >= addr_low) ? 1'b1 : 1'b0;
+ assign d_bram_select = (d_addr <= addr_high && d_addr >= addr_low) ? 1'b1 : 1'b0;
assign i_instr_out = (i_read_en && i_bram_select) ? memory[i_addr] : 0;
+ assign d_data_out = (d_read_en && d_bram_select) ? memory[d_addr] : external_data;
+
+ assign external_data_wren = !d_bram_select && d_write_en;
+ assign external_data_rden = !d_bram_select && d_read_en;
+
+ assign done_please = d_bram_select && (d_read_en || d_write_en);
master_wb mwb_inst(
@@ -52,11 +66,13 @@ module bus_control #(
.done_o(wb_done_o),
- .d_read_en(d_read_en),
- .d_write_en(d_write_en),
+ .d_read_en(external_data_rden),
+ .d_write_en(external_data_wren),
.d_addr(d_addr),
.d_write_data(d_write_data),
- .d_data_out(d_data_out),
+ .d_data_out(external_data),
+
+ .wbm_done_pls_i(done_please),
.wbm_dat_i(wbm_dat_i),
.wbm_ack_i(wbm_ack_i),
diff --git a/hdl/master_wb.v b/hdl/master_wb.v
index cae1dfc..711b115 100644
--- a/hdl/master_wb.v
+++ b/hdl/master_wb.v
@@ -33,14 +33,15 @@ module master_wb(
output reg [31:0] d_data_out,
// wb signals
- input [31:0] wbm_dat_i,
- input wbm_ack_i,
+ input wbm_done_pls_i,
+ input [31:0] wbm_dat_i,
+ input wbm_ack_i,
output reg [31:0] wbm_dat_o,
- output reg wbm_we_o,
- output [3:0] wbm_sel_o,
+ output reg wbm_we_o,
+ output [3:0] wbm_sel_o,
output reg [31:0] wbm_adr_o,
- output reg wbm_cyc_o,
- output reg wbm_stb_o
+ output reg wbm_cyc_o,
+ output reg wbm_stb_o
);
reg [1:0] state_r;
@@ -50,6 +51,7 @@ module master_wb(
localparam IDLE = 0;
localparam WRITE_ACK = 1;
localparam READ_ACK = 2;
+ localparam DONE_PLS = 3;
reg rd_r, wr_r;
@@ -80,19 +82,22 @@ module master_wb(
case(state_r)
IDLE:
if(d_write_en && !wr_r) begin
- wbm_adr_o <= d_addr;
- wbm_dat_o <= d_write_data;
- wbm_we_o <= 1'b1;
- wbm_stb_o <= 1'b1;
- wbm_cyc_o <= 1'b1;
-
- state_r <= WRITE_ACK;
+ wbm_adr_o <= d_addr;
+ wbm_dat_o <= d_write_data;
+ wbm_we_o <= 1'b1;
+ wbm_stb_o <= 1'b1;
+ wbm_cyc_o <= 1'b1;
+
+ state_r <= WRITE_ACK;
end else if (d_read_en && !rd_r) begin
- wbm_adr_o <= d_addr;
- wbm_stb_o <= 1'b1;
- wbm_cyc_o <= 1'b1;
+ wbm_adr_o <= d_addr;
+ wbm_stb_o <= 1'b1;
+ wbm_cyc_o <= 1'b1;
- state_r <= READ_ACK;
+ state_r <= READ_ACK;
+ end else if (wbm_done_pls_i) begin
+ done_o <= 1'b1;
+ state_r <= DONE_PLS;
end
WRITE_ACK:
if(wbm_ack_i) begin
@@ -105,15 +110,18 @@ module master_wb(
end
READ_ACK:
if(wbm_ack_i) begin
- wbm_stb_o <= 1'b0;
- wbm_cyc_o <= 1'b0;
+ wbm_stb_o <= 1'b0;
+ wbm_cyc_o <= 1'b0;
- d_data_out <= wbm_dat_i;
+ d_data_out <= wbm_dat_i;
- done_o <= 1'b1;
- state_r <= IDLE;
+ done_o <= 1'b1;
+ state_r <= IDLE;
end
-
+ DONE_PLS:
+ if(!wbm_done_pls_i)
+ state_r <= IDLE;
+
endcase
end
diff --git a/sw/test.asm b/sw/test.asm
index 3890cf9..6a8a29d 100644
--- a/sw/test.asm
+++ b/sw/test.asm
@@ -7,12 +7,12 @@
.text /* code goes to text section*/
.ent entry
entry:
- lw $t0, 0x1000 /* t0 = 1*/
- sw $t0, 0x1002
- lw $t1, 0x1001 /* t1 = 1*/
- lw $t1, 0x1000 /* t0 = 1*/
+ lw $t0, 0x1000 /* t0 = 1*/
+ sw $t0, 0x1002
+ lw $t1, 0x1001 /* t1 = 1*/
+ lw $t1, 0x1000 /* t0 = 1*/
add $t0, $t0, $t1 /* t0 = t0 + t1 = 2*/
- sw $t0, 0x1200
+ sw $t0, 0x1200
add $t0, $t0, 0xB /* t0 = t0 + 0xB == 0xD*/
sub $t0, $t0, $t1 /* t0 = t0 - $t1 == 0xC*/
or $t0, $t0, 0x10 /* t0 = t0 | 0x10 == 0x1C*/