diff options
| -rw-r--r-- | conspiracion.qsf | 3 | ||||
| -rw-r--r-- | rtl/core/mmu/arbiter.sv | 113 | ||||
| -rw-r--r-- | rtl/core/mmu/mmu.sv | 91 |
3 files changed, 119 insertions, 88 deletions
diff --git a/conspiracion.qsf b/conspiracion.qsf index 1c4a47b..243cb0a 100644 --- a/conspiracion.qsf +++ b/conspiracion.qsf @@ -230,6 +230,7 @@ set_global_assignment -name SYSTEMVERILOG_FILE rtl/core/decode/ldst/single.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/core/decode/snd.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/core/fetch/fetch.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/core/fetch/prefetch.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/core/mmu/arbiter.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/core/mmu/mmu.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/core/mul.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/core/porch/conds.sv @@ -351,4 +352,4 @@ set_global_assignment -name USE_SIGNALTAP_FILE bus_test.stp set_global_assignment -name SIGNALTAP_FILE bus_test.stp -set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
\ No newline at end of file +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top diff --git a/rtl/core/mmu/arbiter.sv b/rtl/core/mmu/arbiter.sv new file mode 100644 index 0000000..3740539 --- /dev/null +++ b/rtl/core/mmu/arbiter.sv @@ -0,0 +1,113 @@ +module core_mmu_arbiter +( + input logic clk, + rst_n, + + input logic bus_ready, + input word bus_data_rd, + data_data_wr, + input ptr insn_addr, + data_addr, + input logic insn_start, + data_start, + data_write, + + output word bus_data_wr, + output ptr bus_addr, + output logic bus_start, + bus_write, + insn_ready, + data_ready, + output word insn_data_rd, + data_data_rd +); + + enum int unsigned + { + INSN, + DATA + } master, next_master; + + ptr hold_addr; + word hold_data_wr; + logic active, hold_start, hold_write, hold_issue, hold_free, transition; + + assign insn_data_rd = bus_data_rd; + assign data_data_rd = bus_data_rd; + + always_comb begin + next_master = master; + if(bus_ready || !active) + unique case(master) + DATA: next_master = data_start ? DATA : INSN; + INSN: next_master = !data_start && !hold_start ? INSN : DATA; + endcase + + // Causa UNOPTFLAT en Verilator con assign + transition = master != next_master; + hold_issue = transition && hold_start; + hold_free = transition || !hold_start; + + insn_ready = 0; + data_ready = 0; + + unique case(master) + INSN: insn_ready = bus_ready; + DATA: data_ready = bus_ready; + endcase + + unique case(next_master) + INSN: begin + bus_addr = insn_addr; + bus_write = 0; + bus_start = insn_start; + bus_data_wr = {32{1'bx}}; + end + + DATA: begin + bus_addr = data_addr; + bus_write = data_write; + bus_start = data_start; + bus_data_wr = data_data_wr; + end + endcase + + if(hold_issue) begin + bus_addr = hold_addr; + bus_write = hold_write; + bus_start = 1; + bus_data_wr = hold_data_wr; + end + end + + always_ff @(posedge clk or negedge rst_n) + if(!rst_n) begin + master <= INSN; + active <= 0; + + hold_addr <= 30'b0; + hold_start <= 0; + hold_write <= 0; + hold_data_wr <= 0; + end else begin + master <= next_master; + active <= bus_start || (active && !bus_ready); + + if(hold_free) + unique case(next_master) + INSN: begin + hold_addr <= data_addr; + hold_start <= data_start; + hold_write <= data_write; + hold_data_wr <= data_data_wr; + end + + DATA: begin + hold_addr <= insn_addr; + hold_start <= insn_start; + hold_write <= 0; + end + endcase + end + +endmodule diff --git a/rtl/core/mmu/mmu.sv b/rtl/core/mmu/mmu.sv index 5928d00..a4be70e 100644 --- a/rtl/core/mmu/mmu.sv +++ b/rtl/core/mmu/mmu.sv @@ -22,93 +22,10 @@ module core_mmu data_data_rd ); - enum int unsigned - { - INSN, - DATA - } master, next_master; - - ptr hold_addr; - word hold_data_wr; - logic active, hold_start, hold_write, hold_issue, hold_free, transition; - //TODO - assign insn_data_rd = bus_data_rd; - assign data_data_rd = bus_data_rd; - - always_comb begin - next_master = master; - if(bus_ready || !active) - unique case(master) - DATA: next_master = data_start ? DATA : INSN; - INSN: next_master = !data_start && !hold_start ? INSN : DATA; - endcase - - // Causa UNOPTFLAT en Verilator con assign - transition = master != next_master; - hold_issue = transition && hold_start; - hold_free = transition || !hold_start; - - insn_ready = 0; - data_ready = 0; - - unique case(master) - INSN: insn_ready = bus_ready; - DATA: data_ready = bus_ready; - endcase - - unique case(next_master) - INSN: begin - bus_addr = insn_addr; - bus_write = 0; - bus_start = insn_start; - bus_data_wr = {32{1'bx}}; - end - - DATA: begin - bus_addr = data_addr; - bus_write = data_write; - bus_start = data_start; - bus_data_wr = data_data_wr; - end - endcase - - if(hold_issue) begin - bus_addr = hold_addr; - bus_write = hold_write; - bus_start = 1; - bus_data_wr = hold_data_wr; - end - end - - always_ff @(posedge clk or negedge rst_n) - if(!rst_n) begin - master <= INSN; - active <= 0; - - hold_addr <= 30'b0; - hold_start <= 0; - hold_write <= 0; - hold_data_wr <= 0; - end else begin - master <= next_master; - active <= bus_start || (active && !bus_ready); - - if(hold_free) - unique case(next_master) - INSN: begin - hold_addr <= data_addr; - hold_start <= data_start; - hold_write <= data_write; - hold_data_wr <= data_data_wr; - end - - DATA: begin - hold_addr <= insn_addr; - hold_start <= insn_start; - hold_write <= 0; - end - endcase - end + core_mmu_arbiter arbiter + ( + .* + ); endmodule |
