aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbsv <s.bikovsky@d1.ifmo.ru>2015-10-18 23:09:48 +0300
committerbsv <s.bikovsky@d1.ifmo.ru>2015-10-18 23:09:48 +0300
commit7056b75cb7d2880fc519b765a9d47dfc624a3f00 (patch)
tree8f1176eba62e70455952f68785fa0ddad937e9bd
parentfceae9c0ed158d26f9884412c42d267dea53eed6 (diff)
downloadMIPSLabs-7056b75cb7d2880fc519b765a9d47dfc624a3f00.zip
MIPSLabs-7056b75cb7d2880fc519b765a9d47dfc624a3f00.tar.gz
MIPSLabs-7056b75cb7d2880fc519b765a9d47dfc624a3f00.tar.bz2
add wishbone
-rw-r--r--hdl/dp_memory.v60
-rw-r--r--hdl/ex_stage.v2
-rw-r--r--hdl/gpio_wb.v63
-rw-r--r--hdl/hazard_unit.v32
-rw-r--r--hdl/id_stage.v60
-rw-r--r--hdl/if_stage.v15
-rw-r--r--hdl/mem_stage.v2
-rw-r--r--hdl/mips_system.v136
-rw-r--r--hdl/pipeline.v22
-rwxr-xr-xhdl/ram_wb/ram_wb.v61
-rwxr-xr-xhdl/ram_wb/wb_ram_sc_sw.v26
-rw-r--r--hdl/testbench.v17
-rw-r--r--hdl/wb/wb.vhd190
-rw-r--r--sw/test.asm8
14 files changed, 611 insertions, 83 deletions
diff --git a/hdl/dp_memory.v b/hdl/dp_memory.v
index 5064df7..d4ca2b8 100644
--- a/hdl/dp_memory.v
+++ b/hdl/dp_memory.v
@@ -4,16 +4,31 @@
Dual-port Instrcution/Data memory
*/
-module dp_memory( input wire clk,
- input wire i_read_en,
- input wire [31:0] i_addr,
- output wire [31:0] i_instr_out,
+module dp_memory(
+ input wire clk,
+ input wire rst,
+ input wire i_read_en,
+ input wire [31:0] i_addr,
+ output wire [31:0] i_instr_out,
+
+ output wb_done_o,
- input wire d_read_en,
- input wire d_write_en,
- input wire [31:0] d_addr,
- input wire [31:0] d_write_data,
- output wire [31:0] d_data_out );
+ input wire d_read_en,
+ input wire d_write_en,
+ input wire [31:0] d_addr,
+ input wire [31:0] d_write_data,
+ output wire [31:0] d_data_out,
+
+ // wb signals
+ input [31:0] wbm_dat_i,
+ input wbm_ack_i,
+ output [31:0] wbm_dat_o,
+ output wbm_we_o,
+ output [3:0] wbm_sel_o,
+ output [31:0] wbm_adr_o,
+ output wbm_cyc_o,
+ output wbm_stb_o
+);
localparam mem_high_addr = 32'h00000400;
@@ -22,7 +37,7 @@ module dp_memory( input wire clk,
reg [31:0] mem[0:mem_high_addr - 1];
initial begin
- $readmemh("./sw/test.rom", mem);
+ $readmemh("../../sw/test.rom", mem);
end
assign i_bram_select = (i_addr < mem_high_addr) ? 1'b1 : 1'b0;
@@ -34,7 +49,30 @@ module dp_memory( input wire clk,
end
assign i_instr_out = (i_read_en && i_bram_select) ? mem[i_addr] : 0;
- assign d_data_out = (d_read_en && d_bram_select) ? mem[d_addr] : 0;
+ //assign d_data_out = (d_read_en && d_bram_select) ? mem[d_addr] : 0;
+
+ master_wb mwb_inst(
+
+ .clk(clk),
+ .rst(rst),
+
+ .done_o(wb_done_o),
+
+ .d_read_en(d_read_en),
+ .d_write_en(d_write_en),
+ .d_addr(d_addr),
+ .d_write_data(d_write_data),
+ .d_data_out(d_data_out),
+
+ .wbm_dat_i(wbm_dat_i),
+ .wbm_ack_i(wbm_ack_i),
+ .wbm_dat_o(wbm_dat_o),
+ .wbm_we_o(wbm_we_o),
+ .wbm_sel_o(wbm_sel_o),
+ .wbm_adr_o(wbm_adr_o),
+ .wbm_cyc_o(wbm_cyc_o),
+ .wbm_stb_o(wbm_stb_o)
+ );
endmodule
diff --git a/hdl/ex_stage.v b/hdl/ex_stage.v
index 082113e..5a7e3d3 100644
--- a/hdl/ex_stage.v
+++ b/hdl/ex_stage.v
@@ -8,6 +8,8 @@ module ex_stage( input clk,
input ex_alu_src_b,
input ex_dst_reg_sel,
input [1:0] ex_alu_op,
+
+ input pstop_i,
input [31:0] A,
input [31:0] B,
diff --git a/hdl/gpio_wb.v b/hdl/gpio_wb.v
new file mode 100644
index 0000000..773c1a6
--- /dev/null
+++ b/hdl/gpio_wb.v
@@ -0,0 +1,63 @@
+module gpio_wb(
+
+ // system signals
+ input clk_i,
+ input rst_i,
+
+ // wb signals
+ input [31:0] dat_i,
+ output reg [31:0] dat_o,
+ input [31:0] adr_i,
+ input we_i,
+ input [3:0] sel_i,
+ input cyc_i,
+ input stb_i,
+ output reg ack_o,
+
+ // func signals
+ output reg [7:0] gpio_o
+);
+
+localparam BASE_ADDR = 32'h00000400;
+
+localparam IDLE = 0;
+localparam ACK = 1;
+
+wire read = cyc_i & stb_i & !we_i;
+wire write = cyc_i & stb_i & we_i;
+
+reg state_r;
+
+always@(posedge clk_i, posedge rst_i)
+ if(rst_i) begin
+ state_r <= 0;
+ ack_o <= 1'b0;
+ gpio_o <= 0;
+ dat_o <= 0;
+ end else begin
+
+ ack_o <= 1'b0;
+
+ case(state_r)
+ IDLE:
+ begin
+ if(write) begin
+ if(adr_i == BASE_ADDR)
+ gpio_o <= dat_i[7:0];
+ ack_o <= 1'b1;
+ state_r <= ACK;
+ end else if(read) begin
+ dat_o <= (adr_i == BASE_ADDR)? gpio_o: 0;
+ state_r <= ACK;
+ end
+ end
+ ACK:
+ begin
+ ack_o <= 1'b0;
+ state_r <= IDLE;
+ end
+ endcase
+ end
+
+
+endmodule
diff --git a/hdl/hazard_unit.v b/hdl/hazard_unit.v
index 4fcee51..2af5896 100644
--- a/hdl/hazard_unit.v
+++ b/hdl/hazard_unit.v
@@ -1,11 +1,15 @@
`timescale 1ns / 1ps
-module hazard_unit( //input clk, isn't needed for now
- //input rst, isn't needed for now
+module hazard_unit( input clk, // isn't needed for now
+ input rst, // isn't needed for now
input [4:0] ex_dst_reg,
input [4:0] mem_dst_reg,
input [4:0] id_rs,
- input [4:0] id_rt,
+ input [4:0] id_rt,
+
+ input wb_done_i,
+
+ output pstop_o,
input [5:0] mem_opcode,
input [5:0] ex_opcode,
@@ -17,13 +21,29 @@ module hazard_unit( //input clk, isn't needed for now
output pc_write,
output if_id_write_en,
- output reg hazard_detected );
+ output hazard_detected_o );
localparam LW = 6'b100011,
+ SW = 6'b101011,
BEQ = 6'b000100;
- assign pc_write = ~hazard_detected;
- assign if_id_write_en = ~hazard_detected;
+ assign pc_write = ~hazard_detected_o;
+ assign if_id_write_en = ~hazard_detected_o;
+
+ reg mem_wait_r;
+ reg hazard_detected;
+
+ assign hazard_detected_o = hazard_detected;
+
+ assign pstop_o = mem_wait_r;
+
+ always@(posedge clk, posedge rst)
+ if(rst || wb_done_i) begin
+ mem_wait_r = 0;
+ end else begin
+ if (id_opcode == LW || id_opcode == SW)
+ mem_wait_r = (id_opcode == LW || id_opcode == SW);
+ end
reg [1:0] coincidence;
diff --git a/hdl/id_stage.v b/hdl/id_stage.v
index 43a6b03..58d3dd6 100644
--- a/hdl/id_stage.v
+++ b/hdl/id_stage.v
@@ -14,6 +14,7 @@ module id_stage( input clk, rst,
input [31:0] mem_fwd_val, wb_fwd_val, // forwarded data values
input hazard,
+ input pstop_i,
//outputs
output [4:0] id_rs,
@@ -135,33 +136,40 @@ module id_stage( input clk, rst,
ID_EX_ex_alu_op <= 0;
end
else begin
- ID_EX_A <= A;
- ID_EX_B <= B;
- ID_EX_rt <= id_rt;
- ID_EX_rs <= id_rs;
- ID_EX_rd <= instruction[15:11];
- ID_EX_opcode <= id_opcode;
- ID_EX_sign_extend_offset <= sign_extend_offset;
- if (is_nop || hazard) begin
- ID_EX_wb_reg_write <= 0;
- ID_EX_wb_mem_to_reg <= 0;
- ID_EX_mem_read <= 0;
- ID_EX_mem_write <= 0;
- ID_EX_ex_imm_command <= 0;
- ID_EX_ex_alu_src_b <= 0;
- ID_EX_ex_dst_reg_sel <= 0;
- ID_EX_ex_alu_op <= 0;
- end
- else begin
- ID_EX_wb_reg_write <= wb_reg_write;
- ID_EX_wb_mem_to_reg <= wb_mem_to_reg;
- ID_EX_mem_read <= mem_read;
- ID_EX_mem_write <= mem_write;
- ID_EX_ex_imm_command <= ex_imm_command;
- ID_EX_ex_alu_src_b <= ex_alu_src_b;
- ID_EX_ex_dst_reg_sel <= ex_dst_reg_sel;
- ID_EX_ex_alu_op <= ex_alu_op;
+ if(!pstop_i) begin
+ ID_EX_A <= A;
+ ID_EX_B <= B;
+ ID_EX_rt <= id_rt;
+ ID_EX_rs <= id_rs;
+ ID_EX_rd <= instruction[15:11];
+
+ ID_EX_opcode <= id_opcode;
+
+ ID_EX_sign_extend_offset <= sign_extend_offset;
+ end
+
+ if(!pstop_i) begin
+ if (is_nop || hazard) begin
+ ID_EX_wb_reg_write <= 0;
+ ID_EX_wb_mem_to_reg <= 0;
+ ID_EX_mem_read <= 0;
+ ID_EX_mem_write <= 0;
+ ID_EX_ex_imm_command <= 0;
+ ID_EX_ex_alu_src_b <= 0;
+ ID_EX_ex_dst_reg_sel <= 0;
+ ID_EX_ex_alu_op <= 0;
+ end
+ else begin
+ ID_EX_wb_reg_write <= wb_reg_write;
+ ID_EX_wb_mem_to_reg <= wb_mem_to_reg;
+ ID_EX_mem_read <= mem_read;
+ ID_EX_mem_write <= mem_write;
+ ID_EX_ex_imm_command <= ex_imm_command;
+ ID_EX_ex_alu_src_b <= ex_alu_src_b;
+ ID_EX_ex_dst_reg_sel <= ex_dst_reg_sel;
+ ID_EX_ex_alu_op <= ex_alu_op;
+ end
end
end
end
diff --git a/hdl/if_stage.v b/hdl/if_stage.v
index ee8818c..02f4cd0 100644
--- a/hdl/if_stage.v
+++ b/hdl/if_stage.v
@@ -8,6 +8,8 @@ module if_stage( input clk, rst,
input if_id_write_en,
input pc_write,
input [1:0] pc_source,
+
+ input pstop_i,
output i_read_en,
output [31:0] i_addr,
@@ -21,6 +23,11 @@ module if_stage( input clk, rst,
reg [31:0] pc_reg, pc_next; // Program counter (PC)
wire [31:0] next_i_addr;
+
+ localparam LW = 6'b100011,
+ SW = 6'b101011;
+
+ wire mem_op = (IF_ID_instruction[31:26] == LW) || (IF_ID_instruction[31:26] == SW);
//logic
assign next_i_addr = pc_reg + 4;
@@ -41,7 +48,7 @@ module if_stage( input clk, rst,
if (rst)
pc_reg <= 0;
else begin
- if (pc_write)
+ if (pc_write && !(pstop_i || mem_op))
pc_reg <= pc_next;
end
end
@@ -53,9 +60,9 @@ module if_stage( input clk, rst,
IF_ID_instruction <= 0;
end
else begin
- if ( if_id_write_en ) begin
- IF_ID_next_i_addr <= pc_reg + 4;
- IF_ID_instruction <= i_instr_in;
+ if ( if_id_write_en) begin
+ IF_ID_next_i_addr <= next_i_addr;
+ IF_ID_instruction <= !(pstop_i || mem_op)? i_instr_in: 0;
end
end
end
diff --git a/hdl/mem_stage.v b/hdl/mem_stage.v
index 79a211d..d0a651e 100644
--- a/hdl/mem_stage.v
+++ b/hdl/mem_stage.v
@@ -12,6 +12,8 @@ module mem_stage (
input wb_reg_write,
input wb_mem_to_reg,
+ input pstop_i,
+
output reg [4:0] MEM_WB_dst_reg,
output reg MEM_WB_reg_write,
output reg MEM_WB_mem_to_reg,
diff --git a/hdl/mips_system.v b/hdl/mips_system.v
index b829c24..759500b 100644
--- a/hdl/mips_system.v
+++ b/hdl/mips_system.v
@@ -2,14 +2,12 @@
MIPS System: CPU Core + Memory
*/
-module mips_system ( input wire clk,
- input wire rst,
-
- output mem_instr_read,
- output [31:0] mem_instr_addr_bus, mem_instr_read_bus,
-
- output mem_data_write, mem_data_read,
- output [31:0] mem_data_addr_bus, mem_data_read_bus, mem_data_write_bus );
+module mips_system (
+ input wire clk,
+ input wire rst,
+
+ output [7:0] led
+);
wire i_read_en;
wire [31:0] i_addr;
@@ -19,21 +17,112 @@ module mips_system ( input wire clk,
wire [31:0] d_addr;
wire [31:0] d_write_data;
wire [31:0] d_read_data;
+
+ // GPIO wb signals
+ wire [31:0] gpio_dat_i;
+ wire [31:0] gpio_dat_o;
+ wire [31:0] gpio_adr_i;
+ wire gpio_we_i;
+ wire [3:0] gpio_sel_i;
+ wire gpio_cyc_i;
+ wire gpio_stb_i;
+ wire gpio_ack_o;
+
+ // MIPS wb signals
+ wire [31:0] mips_wbm_dat_i;
+ wire mips_wbm_ack_i;
+ wire [31:0] mips_wbm_dat_o;
+ wire mips_wbm_we_o;
+ wire [3:0] mips_wbm_sel_o;
+ wire [31:0] mips_wbm_adr_o;
+ wire mips_wbm_cyc_o;
+ wire mips_wbm_stb_o;
+
+ // RAM wishbone signals
+ wire [31:0] ram_dat_i;
+ wire [31:0] ram_dat_o;
+ wire [31:0] ram_addr_i;
+ wire ram_we_i;
+ wire [3:0] ram_sel_i;
+ wire ram_cyc_i;
+ wire ram_stb_i;
+ wire ram_ack_o;
+ wire [2:0] ram_cti_i = 0; // classic cycle
- assign mem_instr_read = i_read_en;
- assign mem_instr_addr_bus = i_addr;
- assign mem_instr_read_bus = i_instr;
+ gpio_wb gpio_inst(
+
+ // system signals
+ .clk_i(clk),
+ .rst_i(rst),
+
+ // wb signals
+ .dat_i(gpio_dat_i),
+ .dat_o(gpio_dat_o),
+ .adr_i(gpio_adr_i),
+ .we_i(gpio_we_i),
+ .sel_i(gpio_sel_i),
+ .cyc_i(gpio_cyc_i),
+ .stb_i(gpio_stb_i),
+ .ack_o(gpio_ack_o),
+
+ // func signals
+ .gpio_o(led)
+ );
- assign mem_data_write = d_write_en;
- assign mem_data_read = d_read_en;
+ ram_wb ram_inst(
+ .dat_i(ram_dat_i),
+ .dat_o(ram_dat_o),
+ .adr_i(ram_addr_i),
+ .we_i(ram_we_i),
+ .sel_i(ram_sel_i),
+ .cyc_i(ram_cyc_i),
+ .stb_i(ram_stb_i),
+ .ack_o(ram_ack_o),
+ .cti_i(ram_cti_i),
+ .clk_i(clk),
+ .rst_i(rst)
+ );
- assign mem_data_addr_bus = d_addr;
- assign mem_data_read_bus = d_read_data;
- assign mem_data_write_bus = d_write_data;
+ intercon wb_inst (
+ // wishbone master port(s)
+ // mips_wbm
+ .mips_wbm_dat_i(mips_wbm_dat_i),
+ .mips_wbm_ack_i(mips_wbm_ack_i),
+ .mips_wbm_dat_o(mips_wbm_dat_o),
+ .mips_wbm_we_o(mips_wbm_we_o),
+ .mips_wbm_sel_o(mips_wbm_sel_o),
+ .mips_wbm_adr_o(mips_wbm_adr_o),
+ .mips_wbm_cyc_o(mips_wbm_cyc_o),
+ .mips_wbm_stb_o(mips_wbm_stb_o),
+ // wishbone slave port(s)
+ // ram_wbs
+ .ram_wbs_dat_o(ram_dat_o),
+ .ram_wbs_ack_o(ram_ack_o),
+ .ram_wbs_dat_i(ram_dat_i),
+ .ram_wbs_we_i(ram_we_i),
+ .ram_wbs_sel_i(ram_sel_i),
+ .ram_wbs_adr_i(ram_addr_i),
+ .ram_wbs_cyc_i(ram_cyc_i),
+ .ram_wbs_stb_i(ram_stb_i),
+ // wbs
+ .wbs_dat_o(gpio_dat_o),
+ .wbs_ack_o(gpio_ack_o),
+ .wbs_dat_i(gpio_dat_i),
+ .wbs_we_i(gpio_we_i),
+ .wbs_sel_i(gpio_sel_i),
+ .wbs_adr_i(gpio_adr_i),
+ .wbs_cyc_i(gpio_cyc_i),
+ .wbs_stb_i(gpio_stb_i),
+ // clock and reset
+ .clk(clk),
+ .reset(rst)
+ );
+
pipeline pipeline_inst (
.clk(clk),
.rst(rst),
+ .wb_done_i(wb_done),
.i_read_en(i_read_en),
.i_addr(i_addr),
.i_instr_in(i_instr),
@@ -45,6 +134,7 @@ module mips_system ( input wire clk,
dp_memory memory_inst (
.clk(clk),
+ .rst(rst),
.i_read_en(i_read_en),
.i_addr(i_addr),
.i_instr_out(i_instr),
@@ -52,6 +142,18 @@ module mips_system ( input wire clk,
.d_write_en(d_write_en),
.d_addr(d_addr),
.d_write_data(d_write_data),
- .d_data_out(d_read_data));
+ .d_data_out(d_read_data),
+
+ .wb_done_o(wb_done),
+
+ .wbm_dat_i(mips_wbm_dat_i),
+ .wbm_ack_i(mips_wbm_ack_i),
+ .wbm_dat_o(mips_wbm_dat_o),
+ .wbm_we_o(mips_wbm_we_o),
+ .wbm_sel_o(mips_wbm_sel_o),
+ .wbm_adr_o(mips_wbm_adr_o),
+ .wbm_cyc_o(mips_wbm_cyc_o),
+ .wbm_stb_o(mips_wbm_stb_o)
+ );
endmodule // mips_system
diff --git a/hdl/pipeline.v b/hdl/pipeline.v
index 918106f..bd18ddc 100644
--- a/hdl/pipeline.v
+++ b/hdl/pipeline.v
@@ -11,6 +11,8 @@ module pipeline ( input wire clk,
output [31:0] i_addr,
input [31:0] i_instr_in,
+
+ input wb_done_i,
output wire d_read_en,
output wire d_write_en,
@@ -79,6 +81,9 @@ module pipeline ( input wire clk,
if_stage ifetch_inst(
.clk ( clk ),
.rst ( rst ),
+
+ .pstop_i(pstop),
+
.if_id_write_en ( if_id_write_en ),
.pc_write ( pc_write ),
.pc_source ( pc_source ),
@@ -91,9 +96,12 @@ module pipeline ( input wire clk,
.IF_ID_next_i_addr ( next_i_addr ));
hazard_unit hazard_inst(
-// .clk ( clk ), isn't needed for now
-// .rst ( rst ), isn't needed for now
+ .clk ( clk ), // isn't needed for now
+ .rst ( rst ), // isn't needed for now
.ex_dst_reg ( ex_dst_reg ),
+
+ .pstop_o(pstop),
+
.mem_dst_reg ( EX_MEM_dst_reg ),
.id_rs ( id_rs ),
.id_rt ( id_rt ),
@@ -105,7 +113,8 @@ module pipeline ( input wire clk,
.mem_reg_write ( EX_MEM_wb_reg_write ),
.pc_write ( pc_write ),
.if_id_write_en ( if_id_write_en ),
- .hazard_detected ( hazard_detected ));
+ .wb_done_i(wb_done_i),
+ .hazard_detected_o ( hazard_detected ));
forwarding_unit forwarding_inst(
.ex_mem_reg_write (EX_MEM_wb_reg_write),
@@ -130,6 +139,8 @@ module pipeline ( input wire clk,
.instruction ( i_fetched ),
.next_i_addr ( next_i_addr ), // instruction fetched, next instruction address
+ .pstop_i(pstop),
+
.rs_fwd_sel ( if_rs_forward_control ), // forwarding control signals
.rt_fwd_sel ( id_rt_forward_control ), // forwarding control signals
.mem_fwd_val ( EX_MEM_alu_result ), // forwarded data values from MEM
@@ -167,6 +178,9 @@ module pipeline ( input wire clk,
.wb_reg_write ( ID_EX_wb_reg_write ),
.wb_mem_to_reg ( ID_EX_wb_mem_to_reg ),
.mem_read ( ID_EX_mem_read ),
+
+ .pstop_i(pstop),
+
.mem_write ( ID_EX_mem_write ),
.ex_imm_command ( ID_EX_ex_imm_command ),
.ex_alu_src_b ( ID_EX_ex_alu_src_b ),
@@ -200,6 +214,8 @@ module pipeline ( input wire clk,
.mem_write ( EX_MEM_mem_write ),
.alu_result ( EX_MEM_alu_result ),
.B ( EX_MEM_B_value ),
+ .pstop_i(pstop),
+
.dst_reg ( EX_MEM_dst_reg ),
.wb_reg_write ( EX_MEM_wb_reg_write ),
.wb_mem_to_reg ( EX_MEM_wb_mem_to_reg ),
diff --git a/hdl/ram_wb/ram_wb.v b/hdl/ram_wb/ram_wb.v
new file mode 100755
index 0000000..0f02c08
--- /dev/null
+++ b/hdl/ram_wb/ram_wb.v
@@ -0,0 +1,61 @@
+module ram_wb ( dat_i, dat_o, adr_i, we_i, sel_i, cyc_i, stb_i, ack_o, cti_i, clk_i, rst_i);
+
+ parameter dat_width = 32;
+ parameter adr_width = 10;
+ parameter mem_size = 1024;
+
+ // wishbone signals
+ input [31:0] dat_i;
+ output [31:0] dat_o;
+ input [adr_width-1:0] adr_i;
+ input we_i;
+ input [3:0] sel_i;
+ input cyc_i;
+ input stb_i;
+ output reg ack_o;
+ input [2:0] cti_i;
+
+ // clock
+ input clk_i;
+ // async reset
+ input rst_i;
+
+ wire [31:0] wr_data;
+
+ // mux for data to ram
+ assign wr_data[31:24] = sel_i[3] ? dat_i[31:24] : dat_o[31:24];
+ assign wr_data[23:16] = sel_i[2] ? dat_i[23:16] : dat_o[23:16];
+ assign wr_data[15: 8] = sel_i[1] ? dat_i[15: 8] : dat_o[15: 8];
+ assign wr_data[ 7: 0] = sel_i[0] ? dat_i[ 7: 0] : dat_o[ 7: 0];
+
+ ram
+ #
+ (
+ .dat_width(dat_width),
+ .adr_width(adr_width),
+ .mem_size(mem_size)
+ )
+ ram0
+ (
+ .dat_i(wr_data),
+ .dat_o(dat_o),
+ .adr_i(adr_i),
+ .we_i(we_i & ack_o),
+ .clk(clk_i)
+ );
+
+ // ack_o
+ always @ (posedge clk_i or posedge rst_i)
+ if (rst_i)
+ ack_o <= 1'b0;
+ else
+ if (!ack_o) begin
+ if (cyc_i & stb_i)
+ ack_o <= 1'b1; end
+ else
+ if ((sel_i != 4'b1111) | (cti_i == 3'b000) | (cti_i == 3'b111))
+ ack_o <= 1'b0;
+
+endmodule
+
+ \ No newline at end of file
diff --git a/hdl/ram_wb/wb_ram_sc_sw.v b/hdl/ram_wb/wb_ram_sc_sw.v
new file mode 100755
index 0000000..c6a9019
--- /dev/null
+++ b/hdl/ram_wb/wb_ram_sc_sw.v
@@ -0,0 +1,26 @@
+module ram (dat_i, dat_o, adr_i, we_i, clk );
+
+ parameter dat_width = 32;
+ parameter adr_width = 10;
+ parameter mem_size = 1024;
+
+ input [dat_width-1:0] dat_i;
+ input [adr_width-1:0] adr_i;
+ input we_i;
+ output reg [dat_width-1:0] dat_o;
+ input clk;
+
+ reg [dat_width-1:0] ram [0:mem_size - 1] /* synthesis ram_style = no_rw_check */;
+
+ initial begin
+ $readmemh("../../sw/test.rom", ram);
+ end
+
+ always @ (posedge clk)
+ begin
+ dat_o <= ram[adr_i];
+ if (we_i)
+ ram[adr_i] <= dat_i;
+ end
+
+endmodule // ram
diff --git a/hdl/testbench.v b/hdl/testbench.v
index a980d65..cde4467 100644
--- a/hdl/testbench.v
+++ b/hdl/testbench.v
@@ -8,26 +8,15 @@ module testbench;
reg mips_rst;
//Outputs
- wire mem_instr_read;
- wire [31:0] mem_instr_addr_bus, mem_instr_read_bus;
-
- wire mem_data_write, mem_data_read;
- wire [31:0] mem_data_addr_bus, mem_data_read_bus, mem_data_write_bus;
+ wire [7:0] led;
//Instantiate the Unit Under Test (UUT)
mips_system uut (
.clk(mips_clk),
.rst(mips_rst),
- .mem_instr_read(mem_instr_read),
- .mem_instr_addr_bus(mem_instr_addr_bus),
- .mem_instr_read_bus(mem_instr_read_bus),
-
- .mem_data_write(mem_data_write),
- .mem_data_read(mem_data_read),
- .mem_data_addr_bus(mem_data_addr_bus),
- .mem_data_read_bus(mem_data_read_bus),
- .mem_data_write_bus(mem_data_write_bus));
+ .led(led)
+ );
initial begin
mips_rst = 1;
diff --git a/hdl/wb/wb.vhd b/hdl/wb/wb.vhd
new file mode 100644
index 0000000..c54b56e
--- /dev/null
+++ b/hdl/wb/wb.vhd
@@ -0,0 +1,190 @@
+-- Generated by PERL program wishbone.pl. Do not edit this file.
+--
+-- For defines see wishbone.defines
+--
+-- Generated Sun Oct 18 18:30:29 2015
+--
+-- Wishbone masters:
+-- mips_wbm
+--
+-- Wishbone slaves:
+-- ram_wbs
+-- baseadr 0x00000000 - size 0x00000400
+-- wbs
+-- baseadr 0x00000400 - size 0x00000400
+-----------------------------------------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+package intercon_package is
+
+
+function "and" (
+ l : std_logic_vector;
+ r : std_logic)
+return std_logic_vector;
+end intercon_package;
+package body intercon_package is
+
+function "and" (
+ l : std_logic_vector;
+ r : std_logic)
+return std_logic_vector is
+ variable result : std_logic_vector(l'range);
+begin -- "and"
+ for i in l'range loop
+ result(i) := l(i) and r;
+end loop; -- i
+return result;
+end "and";
+end intercon_package;
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+entity trafic_supervision is
+
+ generic (
+ priority : integer := 1;
+ tot_priority : integer := 2);
+
+ port (
+ bg : in std_logic; -- bus grant
+ ce : in std_logic; -- clock enable
+ trafic_limit : out std_logic;
+ clk : in std_logic;
+ reset : in std_logic);
+
+end trafic_supervision;
+
+architecture rtl of trafic_supervision is
+
+ signal shreg : std_logic_vector(tot_priority-1 downto 0);
+ signal cntr : integer range 0 to tot_priority;
+
+begin -- rtl
+
+ -- purpose: holds information of usage of latest cycles
+ -- type : sequential
+ -- inputs : clk, reset, ce, bg
+ -- outputs: shreg('left)
+ sh_reg: process (clk,reset)
+ begin -- process shreg
+ if reset = '1' then -- asynchronous reset (active hi)
+ shreg <= (others=>'0');
+ elsif clk'event and clk = '1' then -- rising clock edge
+ if ce='1' then
+ shreg <= shreg(tot_priority-2 downto 0) & bg;
+ end if;
+ end if;
+ end process sh_reg;
+
+ -- purpose: keeps track of used cycles
+ -- type : sequential
+ -- inputs : clk, reset, shreg('left), bg, ce
+ -- outputs: trafic_limit
+ counter: process (clk, reset)
+ begin -- process counter
+ if reset = '1' then -- asynchronous reset (active hi)
+ cntr <= 0;
+ trafic_limit <= '0';
+ elsif clk'event and clk = '1' then -- rising clock edge
+ if ce='1' then
+ if bg='1' and shreg(tot_priority-1)='0' then
+ cntr <= cntr + 1;
+ if cntr=priority-1 then
+ trafic_limit <= '1';
+ end if;
+ elsif bg='0' and shreg(tot_priority-1)='1' then
+ cntr <= cntr - 1;
+ if cntr=priority then
+ trafic_limit <= '0';
+ end if;
+ end if;
+ end if;
+ end if;
+ end process counter;
+
+end rtl;
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use work.intercon_package.all;
+
+entity intercon is
+ port (
+ -- wishbone master port(s)
+ -- mips_wbm
+ mips_wbm_dat_i : out std_logic_vector(31 downto 0);
+ mips_wbm_ack_i : out std_logic;
+ mips_wbm_dat_o : in std_logic_vector(31 downto 0);
+ mips_wbm_we_o : in std_logic;
+ mips_wbm_sel_o : in std_logic_vector(3 downto 0);
+ mips_wbm_adr_o : in std_logic_vector(31 downto 0);
+ mips_wbm_cyc_o : in std_logic;
+ mips_wbm_stb_o : in std_logic;
+ -- wishbone slave port(s)
+ -- ram_wbs
+ ram_wbs_dat_o : in std_logic_vector(31 downto 0);
+ ram_wbs_ack_o : in std_logic;
+ ram_wbs_dat_i : out std_logic_vector(31 downto 0);
+ ram_wbs_we_i : out std_logic;
+ ram_wbs_sel_i : out std_logic_vector(3 downto 0);
+ ram_wbs_adr_i : out std_logic_vector(31 downto 0);
+ ram_wbs_cyc_i : out std_logic;
+ ram_wbs_stb_i : out std_logic;
+ -- wbs
+ wbs_dat_o : in std_logic_vector(31 downto 0);
+ wbs_ack_o : in std_logic;
+ wbs_dat_i : out std_logic_vector(31 downto 0);
+ wbs_we_i : out std_logic;
+ wbs_sel_i : out std_logic_vector(3 downto 0);
+ wbs_adr_i : out std_logic_vector(31 downto 0);
+ wbs_cyc_i : out std_logic;
+ wbs_stb_i : out std_logic;
+ -- clock and reset
+ clk : in std_logic;
+ reset : in std_logic);
+end intercon;
+architecture rtl of intercon is
+ signal ram_wbs_ss : std_logic; -- slave select
+ signal wbs_ss : std_logic; -- slave select
+begin -- rtl
+decoder:block
+ signal adr : std_logic_vector(31 downto 0);
+begin
+adr <= (mips_wbm_adr_o);
+ram_wbs_ss <= '1' when adr(31 downto 10)="0000000000000000000000" else
+'0';
+wbs_ss <= '1' when adr(31 downto 10)="0000000000000000000001" else
+'0';
+ram_wbs_adr_i <= adr(31 downto 0);
+wbs_adr_i <= adr(31 downto 0);
+end block decoder;
+
+mux: block
+ signal cyc, stb, we, ack : std_logic;
+ signal sel : std_logic_vector(3 downto 0);
+ signal dat_m2s, dat_s2m : std_logic_vector(31 downto 0);
+begin
+cyc <= (mips_wbm_cyc_o);
+ram_wbs_cyc_i <= ram_wbs_ss and cyc;
+wbs_cyc_i <= wbs_ss and cyc;
+stb <= (mips_wbm_stb_o);
+ram_wbs_stb_i <= stb;
+wbs_stb_i <= stb;
+we <= (mips_wbm_we_o);
+ram_wbs_we_i <= we;
+wbs_we_i <= we;
+ack <= ram_wbs_ack_o or wbs_ack_o;
+mips_wbm_ack_i <= ack;
+sel <= (mips_wbm_sel_o);
+ram_wbs_sel_i <= sel;
+wbs_sel_i <= sel;
+dat_m2s <= (mips_wbm_dat_o);
+ram_wbs_dat_i <= dat_m2s;
+wbs_dat_i <= dat_m2s;
+dat_s2m <= (ram_wbs_dat_o and ram_wbs_ss) or (wbs_dat_o and wbs_ss);
+mips_wbm_dat_i <= dat_s2m;
+end block mux;
+
+end rtl; \ No newline at end of file
diff --git a/sw/test.asm b/sw/test.asm
index 7712165..496cf37 100644
--- a/sw/test.asm
+++ b/sw/test.asm
@@ -1,14 +1,18 @@
.global entry
.data /* data section*/
- .word 0x0001
+ .word 0x0001
+ .word 0x0002
.word 0xFFFF
.text /* code goes to text section*/
.ent entry
entry:
lw $t0, 0x200 /* t0 = 1*/
- lw $t1, 0x200 /* t1 = 1*/
+ sw $t0, 0x202
+ lw $t1, 0x201 /* t1 = 1*/
+ lw $t1, 0x200 /* t0 = 1*/
add $t0, $t0, $t1 /* t0 = t0 + t1 = 2*/
+ sw $t0, 0x400
add $t0, $t0, 0xB /* t0 = t0 + 0xB == 0xD*/
sub $t0, $t0, $t1 /* t0 = t0 - $t1 == 0xC*/
or $t0, $t0, 0x10 /* t0 = t0 | 0x10 == 0x1C*/