Add basic support for lr/sc instructions from the A extension
This commit is contained in:
parent
c5d6be24f3
commit
5e17bb805e
|
@ -4,6 +4,7 @@ Hazard3 is a 3-stage RISC-V processor, implementing the `RV32I` instruction set
|
||||||
|
|
||||||
* `M`: integer multiply/divide/modulo
|
* `M`: integer multiply/divide/modulo
|
||||||
* `C`: compressed instructions
|
* `C`: compressed instructions
|
||||||
|
* `A` _(partial)_: load reserved/store conditional instructions, with AHB5 HEXCL/HEXOKAY signalling for global monitor queries
|
||||||
* `Zicsr`: CSR access
|
* `Zicsr`: CSR access
|
||||||
* `Zba`: address generation
|
* `Zba`: address generation
|
||||||
* `Zbb`: basic bit manipulation
|
* `Zbb`: basic bit manipulation
|
||||||
|
@ -23,7 +24,8 @@ _Note: the bit manipulation instructions don't have upstream compliance tests at
|
||||||
|
|
||||||
The following are planned for future implementation:
|
The following are planned for future implementation:
|
||||||
|
|
||||||
* `A` extension: atomic memory access
|
* Complete support for the `A` extension: atomic memory operations
|
||||||
|
* Debug trigger unit (breakpoint-only)
|
||||||
|
|
||||||
Hazard3 is still under development.
|
Hazard3 is still under development.
|
||||||
|
|
||||||
|
|
8674
doc/hazard3.pdf
8674
doc/hazard3.pdf
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
||||||
== Instruction Cycle Counts
|
== Instruction Cycle Counts
|
||||||
|
|
||||||
All timings are given assuming perfect bus behaviour (no stalls). Stalling of the `I` bus can delay execution indefinitely, as can stalling of the `D` bus during a load or store.
|
All timings are given assuming perfect bus behaviour (no downstream bus stalls).
|
||||||
|
|
||||||
=== RV32I
|
=== RV32I
|
||||||
|
|
||||||
|
@ -72,6 +72,17 @@ Timings assume the core is configured with `MULDIV_UNROLL = 2` and `MUL_FAST = 1
|
||||||
| `remu rd, rs1, rs2` | 18 |
|
| `remu rd, rs1, rs2` | 18 |
|
||||||
|===
|
|===
|
||||||
|
|
||||||
|
=== A Extension
|
||||||
|
|
||||||
|
[%autowidth.stretch, options="header"]
|
||||||
|
|===
|
||||||
|
| Instruction | Cycles | Note
|
||||||
|
| `lr.w rd, (rs1)` | 1 or 2 | 1 if next instruction is independent, 2 if dependent.footnote:data_dependency[]
|
||||||
|
| `sc.w rd, rs2, (rs1)` | 1 | `lr.w` followed by `sc.w` always inserts a dependency stall.footnote:lr_to_sc[A 1-cycle pipeline bubble is inserted in between an `lr.w` and an immediately-following `sc.w`, so that the store can be suppressed by a reservation failure on the load. It does not matter whether the `lr.w` and `sc.w` use the same registers. Load reservation may fail if the memory region does not support exclusive transfers.]
|
||||||
|
|===
|
||||||
|
|
||||||
|
AMOs are currently not supported.
|
||||||
|
|
||||||
=== C Extension
|
=== C Extension
|
||||||
|
|
||||||
All C extension 16-bit instructions on Hazard3 are aliases of base RV32I instructions. They perform identically to their 32-bit counterparts.
|
All C extension 16-bit instructions on Hazard3 are aliases of base RV32I instructions. They perform identically to their 32-bit counterparts.
|
||||||
|
|
|
@ -221,8 +221,10 @@ wire [2:0] proc_hsize;
|
||||||
wire [2:0] proc_hburst;
|
wire [2:0] proc_hburst;
|
||||||
wire [3:0] proc_hprot;
|
wire [3:0] proc_hprot;
|
||||||
wire proc_hmastlock;
|
wire proc_hmastlock;
|
||||||
|
wire proc_hexcl;
|
||||||
wire proc_hready;
|
wire proc_hready;
|
||||||
wire proc_hresp;
|
wire proc_hresp;
|
||||||
|
wire proc_hexokay = 1'b1; // No global monitor
|
||||||
wire [W_DATA-1:0] proc_hwdata;
|
wire [W_DATA-1:0] proc_hwdata;
|
||||||
wire [W_DATA-1:0] proc_hrdata;
|
wire [W_DATA-1:0] proc_hrdata;
|
||||||
|
|
||||||
|
@ -264,8 +266,10 @@ hazard3_cpu_1port #(
|
||||||
.ahblm_hburst (proc_hburst),
|
.ahblm_hburst (proc_hburst),
|
||||||
.ahblm_hprot (proc_hprot),
|
.ahblm_hprot (proc_hprot),
|
||||||
.ahblm_hmastlock (proc_hmastlock),
|
.ahblm_hmastlock (proc_hmastlock),
|
||||||
|
.ahblm_hexcl (proc_hexcl),
|
||||||
.ahblm_hready (proc_hready),
|
.ahblm_hready (proc_hready),
|
||||||
.ahblm_hresp (proc_hresp),
|
.ahblm_hresp (proc_hresp),
|
||||||
|
.ahblm_hexokay (proc_hexokay),
|
||||||
.ahblm_hwdata (proc_hwdata),
|
.ahblm_hwdata (proc_hwdata),
|
||||||
.ahblm_hrdata (proc_hrdata),
|
.ahblm_hrdata (proc_hrdata),
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,10 @@ parameter MTVEC_INIT = 32'h00000000,
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// RISC-V ISA and CSR support
|
// RISC-V ISA and CSR support
|
||||||
|
|
||||||
|
// EXTENSION_A: Support for atomic read/modify/write instructions
|
||||||
|
// (currently, only lr.w/sc.w are supported)
|
||||||
|
parameter EXTENSION_A = 1,
|
||||||
|
|
||||||
// EXTENSION_C: Support for compressed (variable-width) instructions
|
// EXTENSION_C: Support for compressed (variable-width) instructions
|
||||||
parameter EXTENSION_C = 1,
|
parameter EXTENSION_C = 1,
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
.RESET_VECTOR (RESET_VECTOR),
|
.RESET_VECTOR (RESET_VECTOR),
|
||||||
.MTVEC_INIT (MTVEC_INIT),
|
.MTVEC_INIT (MTVEC_INIT),
|
||||||
|
.EXTENSION_A (EXTENSION_A),
|
||||||
.EXTENSION_C (EXTENSION_C),
|
.EXTENSION_C (EXTENSION_C),
|
||||||
.EXTENSION_M (EXTENSION_M),
|
.EXTENSION_M (EXTENSION_M),
|
||||||
.EXTENSION_ZBA (EXTENSION_ZBA),
|
.EXTENSION_ZBA (EXTENSION_ZBA),
|
||||||
|
|
|
@ -43,9 +43,11 @@ module hazard3_core #(
|
||||||
|
|
||||||
// Load/store port
|
// Load/store port
|
||||||
output reg bus_aph_req_d,
|
output reg bus_aph_req_d,
|
||||||
|
output wire bus_aph_excl_d,
|
||||||
input wire bus_aph_ready_d,
|
input wire bus_aph_ready_d,
|
||||||
input wire bus_dph_ready_d,
|
input wire bus_dph_ready_d,
|
||||||
input wire bus_dph_err_d,
|
input wire bus_dph_err_d,
|
||||||
|
input wire bus_dph_exokay_d,
|
||||||
|
|
||||||
output reg [W_ADDR-1:0] bus_haddr_d,
|
output reg [W_ADDR-1:0] bus_haddr_d,
|
||||||
output reg [2:0] bus_hsize_d,
|
output reg [2:0] bus_hsize_d,
|
||||||
|
@ -300,6 +302,9 @@ always @ (*) begin
|
||||||
x_stall_raw =
|
x_stall_raw =
|
||||||
|xm_rd && (xm_rd == d_rs1 || xm_rd == d_rs2) ||
|
|xm_rd && (xm_rd == d_rs1 || xm_rd == d_rs2) ||
|
||||||
|mw_rd && (mw_rd == d_rs1 || mw_rd == d_rs2);
|
|mw_rd && (mw_rd == d_rs1 || mw_rd == d_rs2);
|
||||||
|
end else if (|EXTENSION_A && xm_memop == MEMOP_LR_W && d_memop == MEMOP_SC_W) begin
|
||||||
|
// Conditional-store address phase depends on data-phase update of local monitor bit
|
||||||
|
x_stall_raw = 1'b1;
|
||||||
end else if (m_generating_result) begin
|
end else if (m_generating_result) begin
|
||||||
// With the full bypass network, load-use (or fast multiply-use) is the only RAW stall
|
// With the full bypass network, load-use (or fast multiply-use) is the only RAW stall
|
||||||
if (|xm_rd && xm_rd == d_rs1) begin
|
if (|xm_rd && xm_rd == d_rs1) begin
|
||||||
|
@ -358,13 +363,24 @@ hazard3_alu #(
|
||||||
|
|
||||||
// AHB transaction request
|
// AHB transaction request
|
||||||
|
|
||||||
wire x_memop_vld = !d_memop[3];
|
reg mw_local_exclusive_reserved;
|
||||||
wire x_memop_write = d_memop == MEMOP_SW || d_memop == MEMOP_SH || d_memop == MEMOP_SB;
|
|
||||||
|
wire x_memop_vld = d_memop != MEMOP_NONE && !(
|
||||||
|
|EXTENSION_A && d_memop == MEMOP_SC_W && !mw_local_exclusive_reserved
|
||||||
|
);
|
||||||
|
|
||||||
|
wire x_memop_write =
|
||||||
|
d_memop == MEMOP_SW || d_memop == MEMOP_SH || d_memop == MEMOP_SB ||
|
||||||
|
|EXTENSION_A && d_memop == MEMOP_SC_W;
|
||||||
|
|
||||||
wire x_unaligned_addr = d_memop != MEMOP_NONE && (
|
wire x_unaligned_addr = d_memop != MEMOP_NONE && (
|
||||||
bus_hsize_d == HSIZE_WORD && |bus_haddr_d[1:0] ||
|
bus_hsize_d == HSIZE_WORD && |bus_haddr_d[1:0] ||
|
||||||
bus_hsize_d == HSIZE_HWORD && bus_haddr_d[0]
|
bus_hsize_d == HSIZE_HWORD && bus_haddr_d[0]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Always query the global monitor, except for store-conditional suppressed by local monitor.
|
||||||
|
assign bus_aph_excl_d = |EXTENSION_A && (d_memop == MEMOP_LR_W || d_memop == MEMOP_SC_W);
|
||||||
|
|
||||||
always @ (*) begin
|
always @ (*) begin
|
||||||
// Need to be careful not to use anything hready-sourced to gate htrans!
|
// Need to be careful not to use anything hready-sourced to gate htrans!
|
||||||
bus_haddr_d = x_alu_add;
|
bus_haddr_d = x_alu_add;
|
||||||
|
@ -609,7 +625,9 @@ always @ (posedge clk or negedge rst_n) begin
|
||||||
`ifdef FORMAL
|
`ifdef FORMAL
|
||||||
assert(xm_memop != MEMOP_NONE);
|
assert(xm_memop != MEMOP_NONE);
|
||||||
`endif
|
`endif
|
||||||
xm_except <= xm_memop <= MEMOP_LBU ? EXCEPT_LOAD_FAULT : EXCEPT_STORE_FAULT;
|
xm_except <=
|
||||||
|
|EXTENSION_A && xm_memop == MEMOP_LR_W ? EXCEPT_LOAD_FAULT :
|
||||||
|
xm_memop <= MEMOP_LBU ? EXCEPT_LOAD_FAULT : EXCEPT_STORE_FAULT;
|
||||||
xm_wfi <= 1'b0;
|
xm_wfi <= 1'b0;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -648,7 +666,10 @@ assign f_jump_req = x_jump_req || m_trap_enter_vld;
|
||||||
assign f_jump_target = m_trap_enter_vld ? m_trap_addr : x_jump_target;
|
assign f_jump_target = m_trap_enter_vld ? m_trap_addr : x_jump_target;
|
||||||
assign x_jump_not_except = !m_trap_enter_vld;
|
assign x_jump_not_except = !m_trap_enter_vld;
|
||||||
|
|
||||||
wire m_bus_stall = xm_memop != MEMOP_NONE && !bus_dph_ready_d;
|
wire m_bus_stall = xm_memop != MEMOP_NONE && !bus_dph_ready_d && !(
|
||||||
|
|EXTENSION_A && xm_memop == MEMOP_SC_W && !mw_local_exclusive_reserved
|
||||||
|
);
|
||||||
|
|
||||||
assign m_stall = m_bus_stall ||
|
assign m_stall = m_bus_stall ||
|
||||||
(m_trap_enter_vld && !m_trap_enter_rdy && !m_trap_is_irq) ||
|
(m_trap_enter_vld && !m_trap_enter_rdy && !m_trap_is_irq) ||
|
||||||
(xm_wfi && !m_wfi_stall_clear);
|
(xm_wfi && !m_wfi_stall_clear);
|
||||||
|
@ -672,10 +693,9 @@ always @ (*) begin
|
||||||
end
|
end
|
||||||
// Replicate store data to ensure appropriate byte lane is driven
|
// Replicate store data to ensure appropriate byte lane is driven
|
||||||
case (xm_memop)
|
case (xm_memop)
|
||||||
MEMOP_SW: bus_wdata_d = m_wdata;
|
|
||||||
MEMOP_SH: bus_wdata_d = {2{m_wdata[15:0]}};
|
MEMOP_SH: bus_wdata_d = {2{m_wdata[15:0]}};
|
||||||
MEMOP_SB: bus_wdata_d = {4{m_wdata[7:0]}};
|
MEMOP_SB: bus_wdata_d = {4{m_wdata[7:0]}};
|
||||||
default: bus_wdata_d = 32'h0;
|
default: bus_wdata_d = m_wdata; // TODO worth it to mask when not writing? Costs LUTs, saves energy
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
casez ({xm_memop, xm_result[1:0]})
|
casez ({xm_memop, xm_result[1:0]})
|
||||||
|
@ -694,7 +714,10 @@ always @ (*) begin
|
||||||
default: m_rdata_pick_sext = bus_rdata_d;
|
default: m_rdata_pick_sext = bus_rdata_d;
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
if (xm_memop != MEMOP_NONE) begin
|
if (|EXTENSION_A && xm_memop == MEMOP_SC_W) begin
|
||||||
|
// sc.w may fail due to negative response from either local or global monitor.
|
||||||
|
m_result = {31'h0, mw_local_exclusive_reserved && bus_dph_exokay_d};
|
||||||
|
end else if (xm_memop != MEMOP_NONE) begin
|
||||||
m_result = m_rdata_pick_sext;
|
m_result = m_rdata_pick_sext;
|
||||||
end else if (MUL_FAST && m_fast_mul_result_vld) begin
|
end else if (MUL_FAST && m_fast_mul_result_vld) begin
|
||||||
m_result = m_fast_mul_result;
|
m_result = m_fast_mul_result;
|
||||||
|
@ -703,11 +726,28 @@ always @ (*) begin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
// Local monitor update.
|
||||||
|
// - Set on a load-reserved with good response from global monitor
|
||||||
|
// - Cleared by any store-conditional
|
||||||
|
// - Not affected by trap entry (permitted by RISC-V spec)
|
||||||
|
|
||||||
|
always @ (posedge clk or negedge rst_n) begin
|
||||||
|
if (!rst_n) begin
|
||||||
|
mw_local_exclusive_reserved <= 1'b0;
|
||||||
|
end else if (|EXTENSION_A && !m_stall) begin
|
||||||
|
if (xm_memop == MEMOP_SC_W) begin
|
||||||
|
mw_local_exclusive_reserved <= 1'b0;
|
||||||
|
end else if (xm_memop == MEMOP_LR_W) begin
|
||||||
|
mw_local_exclusive_reserved <= bus_dph_exokay_d;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
// Note that exception entry prevents writeback, because the exception entry
|
// Note that exception entry prevents writeback, because the exception entry
|
||||||
// replaces the instruction in M. Interrupt entry does not prevent writeback,
|
// replaces the instruction in M. Interrupt entry does not prevent writeback,
|
||||||
// because the interrupt is notionally inserted in between the instruction in
|
// because the interrupt is notionally inserted in between the instruction in
|
||||||
// M and the instruction in X.
|
// M and the instruction in X.
|
||||||
|
|
||||||
wire m_reg_wen_if_nonzero = !m_bus_stall && xm_except == EXCEPT_NONE;
|
wire m_reg_wen_if_nonzero = !m_bus_stall && xm_except == EXCEPT_NONE;
|
||||||
wire m_reg_wen = |xm_rd && m_reg_wen_if_nonzero;
|
wire m_reg_wen = |xm_rd && m_reg_wen_if_nonzero;
|
||||||
|
|
||||||
|
|
|
@ -40,8 +40,10 @@ module hazard3_cpu_1port #(
|
||||||
output wire [2:0] ahblm_hburst,
|
output wire [2:0] ahblm_hburst,
|
||||||
output reg [3:0] ahblm_hprot,
|
output reg [3:0] ahblm_hprot,
|
||||||
output wire ahblm_hmastlock,
|
output wire ahblm_hmastlock,
|
||||||
|
output reg ahblm_hexcl,
|
||||||
input wire ahblm_hready,
|
input wire ahblm_hready,
|
||||||
input wire ahblm_hresp,
|
input wire ahblm_hresp,
|
||||||
|
input wire ahblm_hexokay,
|
||||||
output wire [W_DATA-1:0] ahblm_hwdata,
|
output wire [W_DATA-1:0] ahblm_hwdata,
|
||||||
input wire [W_DATA-1:0] ahblm_hrdata,
|
input wire [W_DATA-1:0] ahblm_hrdata,
|
||||||
|
|
||||||
|
@ -85,9 +87,11 @@ wire [W_DATA-1:0] core_rdata_i;
|
||||||
|
|
||||||
// Load/store signals
|
// Load/store signals
|
||||||
wire core_aph_req_d;
|
wire core_aph_req_d;
|
||||||
|
wire core_aph_excl_d;
|
||||||
wire core_aph_ready_d;
|
wire core_aph_ready_d;
|
||||||
wire core_dph_ready_d;
|
wire core_dph_ready_d;
|
||||||
wire core_dph_err_d;
|
wire core_dph_err_d;
|
||||||
|
wire core_dph_exokay_d;
|
||||||
|
|
||||||
wire [W_ADDR-1:0] core_haddr_d;
|
wire [W_ADDR-1:0] core_haddr_d;
|
||||||
wire [2:0] core_hsize_d;
|
wire [2:0] core_hsize_d;
|
||||||
|
@ -116,9 +120,11 @@ hazard3_core #(
|
||||||
.bus_rdata_i (core_rdata_i),
|
.bus_rdata_i (core_rdata_i),
|
||||||
|
|
||||||
.bus_aph_req_d (core_aph_req_d),
|
.bus_aph_req_d (core_aph_req_d),
|
||||||
|
.bus_aph_excl_d (core_aph_excl_d),
|
||||||
.bus_aph_ready_d (core_aph_ready_d),
|
.bus_aph_ready_d (core_aph_ready_d),
|
||||||
.bus_dph_ready_d (core_dph_ready_d),
|
.bus_dph_ready_d (core_dph_ready_d),
|
||||||
.bus_dph_err_d (core_dph_err_d),
|
.bus_dph_err_d (core_dph_err_d),
|
||||||
|
.bus_dph_exokay_d (core_dph_exokay_d),
|
||||||
.bus_haddr_d (core_haddr_d),
|
.bus_haddr_d (core_haddr_d),
|
||||||
.bus_hsize_d (core_hsize_d),
|
.bus_hsize_d (core_hsize_d),
|
||||||
.bus_hwrite_d (core_hwrite_d),
|
.bus_hwrite_d (core_hwrite_d),
|
||||||
|
@ -144,7 +150,6 @@ hazard3_core #(
|
||||||
.timer_irq (timer_irq)
|
.timer_irq (timer_irq)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Arbitration state machine
|
// Arbitration state machine
|
||||||
|
|
||||||
|
@ -201,18 +206,21 @@ assign ahblm_hmastlock = 1'b0;
|
||||||
always @ (*) begin
|
always @ (*) begin
|
||||||
if (bus_gnt_d) begin
|
if (bus_gnt_d) begin
|
||||||
ahblm_htrans = HTRANS_NSEQ;
|
ahblm_htrans = HTRANS_NSEQ;
|
||||||
|
ahblm_hexcl = core_aph_excl_d;
|
||||||
ahblm_haddr = core_haddr_d;
|
ahblm_haddr = core_haddr_d;
|
||||||
ahblm_hsize = core_hsize_d;
|
ahblm_hsize = core_hsize_d;
|
||||||
ahblm_hwrite = core_hwrite_d;
|
ahblm_hwrite = core_hwrite_d;
|
||||||
ahblm_hprot = HPROT_DATA;
|
ahblm_hprot = HPROT_DATA;
|
||||||
end else if (bus_gnt_i) begin
|
end else if (bus_gnt_i) begin
|
||||||
ahblm_htrans = HTRANS_NSEQ;
|
ahblm_htrans = HTRANS_NSEQ;
|
||||||
|
ahblm_hexcl = 1'b0;
|
||||||
ahblm_haddr = core_haddr_i;
|
ahblm_haddr = core_haddr_i;
|
||||||
ahblm_hsize = core_hsize_i;
|
ahblm_hsize = core_hsize_i;
|
||||||
ahblm_hwrite = 1'b0;
|
ahblm_hwrite = 1'b0;
|
||||||
ahblm_hprot = HPROT_INSTR;
|
ahblm_hprot = HPROT_INSTR;
|
||||||
end else begin
|
end else begin
|
||||||
ahblm_htrans = HTRANS_IDLE;
|
ahblm_htrans = HTRANS_IDLE;
|
||||||
|
ahblm_hexcl = 1'b0;
|
||||||
ahblm_haddr = {W_ADDR{1'b0}};
|
ahblm_haddr = {W_ADDR{1'b0}};
|
||||||
ahblm_hsize = 3'h0;
|
ahblm_hsize = 3'h0;
|
||||||
ahblm_hwrite = 1'b0;
|
ahblm_hwrite = 1'b0;
|
||||||
|
@ -239,6 +247,7 @@ assign core_dph_err_i = bus_active_dph_i && ahblm_hresp;
|
||||||
assign core_aph_ready_d = ahblm_hready && bus_gnt_d;
|
assign core_aph_ready_d = ahblm_hready && bus_gnt_d;
|
||||||
assign core_dph_ready_d = ahblm_hready && bus_active_dph_d;
|
assign core_dph_ready_d = ahblm_hready && bus_active_dph_d;
|
||||||
assign core_dph_err_d = bus_active_dph_d && ahblm_hresp;
|
assign core_dph_err_d = bus_active_dph_d && ahblm_hresp;
|
||||||
|
assign core_dph_exokay_d = bus_active_dph_d && ahblm_hexokay;
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
|
@ -53,8 +53,10 @@ module hazard3_cpu_2port #(
|
||||||
output wire [2:0] d_hburst,
|
output wire [2:0] d_hburst,
|
||||||
output wire [3:0] d_hprot,
|
output wire [3:0] d_hprot,
|
||||||
output wire d_hmastlock,
|
output wire d_hmastlock,
|
||||||
|
output wire d_hexcl,
|
||||||
input wire d_hready,
|
input wire d_hready,
|
||||||
input wire d_hresp,
|
input wire d_hresp,
|
||||||
|
input wire d_hexokay,
|
||||||
output wire [W_DATA-1:0] d_hwdata,
|
output wire [W_DATA-1:0] d_hwdata,
|
||||||
input wire [W_DATA-1:0] d_hrdata,
|
input wire [W_DATA-1:0] d_hrdata,
|
||||||
|
|
||||||
|
@ -98,9 +100,11 @@ wire [W_DATA-1:0] core_rdata_i;
|
||||||
|
|
||||||
// Load/store signals
|
// Load/store signals
|
||||||
wire core_aph_req_d;
|
wire core_aph_req_d;
|
||||||
|
wire core_aph_excl_d;
|
||||||
wire core_aph_ready_d;
|
wire core_aph_ready_d;
|
||||||
wire core_dph_ready_d;
|
wire core_dph_ready_d;
|
||||||
wire core_dph_err_d;
|
wire core_dph_err_d;
|
||||||
|
wire core_dph_exokay_d;
|
||||||
|
|
||||||
wire [W_ADDR-1:0] core_haddr_d;
|
wire [W_ADDR-1:0] core_haddr_d;
|
||||||
wire [2:0] core_hsize_d;
|
wire [2:0] core_hsize_d;
|
||||||
|
@ -112,8 +116,8 @@ wire [W_DATA-1:0] core_rdata_d;
|
||||||
hazard3_core #(
|
hazard3_core #(
|
||||||
`include "hazard3_config_inst.vh"
|
`include "hazard3_config_inst.vh"
|
||||||
) core (
|
) core (
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.rst_n (rst_n),
|
.rst_n (rst_n),
|
||||||
|
|
||||||
`ifdef RISCV_FORMAL
|
`ifdef RISCV_FORMAL
|
||||||
`RVFI_CONN ,
|
`RVFI_CONN ,
|
||||||
|
@ -129,9 +133,11 @@ hazard3_core #(
|
||||||
.bus_rdata_i (core_rdata_i),
|
.bus_rdata_i (core_rdata_i),
|
||||||
|
|
||||||
.bus_aph_req_d (core_aph_req_d),
|
.bus_aph_req_d (core_aph_req_d),
|
||||||
|
.bus_aph_excl_d (core_aph_excl_d),
|
||||||
.bus_aph_ready_d (core_aph_ready_d),
|
.bus_aph_ready_d (core_aph_ready_d),
|
||||||
.bus_dph_ready_d (core_dph_ready_d),
|
.bus_dph_ready_d (core_dph_ready_d),
|
||||||
.bus_dph_err_d (core_dph_err_d),
|
.bus_dph_err_d (core_dph_err_d),
|
||||||
|
.bus_dph_exokay_d (core_dph_exokay_d),
|
||||||
.bus_haddr_d (core_haddr_d),
|
.bus_haddr_d (core_haddr_d),
|
||||||
.bus_hsize_d (core_hsize_d),
|
.bus_hsize_d (core_hsize_d),
|
||||||
.bus_hwrite_d (core_hwrite_d),
|
.bus_hwrite_d (core_hwrite_d),
|
||||||
|
@ -193,6 +199,7 @@ assign d_haddr = core_haddr_d;
|
||||||
assign d_htrans = core_aph_req_d ? HTRANS_NSEQ : HTRANS_IDLE;
|
assign d_htrans = core_aph_req_d ? HTRANS_NSEQ : HTRANS_IDLE;
|
||||||
assign d_hwrite = core_hwrite_d;
|
assign d_hwrite = core_hwrite_d;
|
||||||
assign d_hsize = core_hsize_d;
|
assign d_hsize = core_hsize_d;
|
||||||
|
assign d_hexcl = core_aph_excl_d;
|
||||||
|
|
||||||
reg dphase_active_d;
|
reg dphase_active_d;
|
||||||
always @ (posedge clk or negedge rst_n)
|
always @ (posedge clk or negedge rst_n)
|
||||||
|
@ -207,6 +214,7 @@ always @ (posedge clk or negedge rst_n)
|
||||||
assign core_aph_ready_d = d_hready && core_aph_req_d;
|
assign core_aph_ready_d = d_hready && core_aph_req_d;
|
||||||
assign core_dph_ready_d = d_hready && dphase_active_d;
|
assign core_dph_ready_d = d_hready && dphase_active_d;
|
||||||
assign core_dph_err_d = dphase_active_d && d_hresp;
|
assign core_dph_err_d = dphase_active_d && d_hresp;
|
||||||
|
assign core_dph_exokay_d = dphase_active_d && d_hexokay;
|
||||||
|
|
||||||
assign core_rdata_d = d_hrdata;
|
assign core_rdata_d = d_hrdata;
|
||||||
assign d_hwdata = core_wdata_d;
|
assign d_hwdata = core_wdata_d;
|
||||||
|
|
|
@ -234,6 +234,7 @@ always @ (*) begin
|
||||||
RV_SB: begin d_aluop = ALUOP_ADD; d_imm = d_imm_s; d_alusrc_b = ALUSRCB_IMM; d_memop = MEMOP_SB; d_rd = X0; end
|
RV_SB: begin d_aluop = ALUOP_ADD; d_imm = d_imm_s; d_alusrc_b = ALUSRCB_IMM; d_memop = MEMOP_SB; d_rd = X0; end
|
||||||
RV_SH: begin d_aluop = ALUOP_ADD; d_imm = d_imm_s; d_alusrc_b = ALUSRCB_IMM; d_memop = MEMOP_SH; d_rd = X0; end
|
RV_SH: begin d_aluop = ALUOP_ADD; d_imm = d_imm_s; d_alusrc_b = ALUSRCB_IMM; d_memop = MEMOP_SH; d_rd = X0; end
|
||||||
RV_SW: begin d_aluop = ALUOP_ADD; d_imm = d_imm_s; d_alusrc_b = ALUSRCB_IMM; d_memop = MEMOP_SW; d_rd = X0; end
|
RV_SW: begin d_aluop = ALUOP_ADD; d_imm = d_imm_s; d_alusrc_b = ALUSRCB_IMM; d_memop = MEMOP_SW; d_rd = X0; end
|
||||||
|
|
||||||
RV_MUL: if (EXTENSION_M) begin d_aluop = ALUOP_MULDIV; d_mulop = M_OP_MUL; end else begin d_invalid_32bit = 1'b1; end
|
RV_MUL: if (EXTENSION_M) begin d_aluop = ALUOP_MULDIV; d_mulop = M_OP_MUL; end else begin d_invalid_32bit = 1'b1; end
|
||||||
RV_MULH: if (EXTENSION_M) begin d_aluop = ALUOP_MULDIV; d_mulop = M_OP_MULH; end else begin d_invalid_32bit = 1'b1; end
|
RV_MULH: if (EXTENSION_M) begin d_aluop = ALUOP_MULDIV; d_mulop = M_OP_MULH; end else begin d_invalid_32bit = 1'b1; end
|
||||||
RV_MULHSU: if (EXTENSION_M) begin d_aluop = ALUOP_MULDIV; d_mulop = M_OP_MULHSU; end else begin d_invalid_32bit = 1'b1; end
|
RV_MULHSU: if (EXTENSION_M) begin d_aluop = ALUOP_MULDIV; d_mulop = M_OP_MULHSU; end else begin d_invalid_32bit = 1'b1; end
|
||||||
|
@ -242,9 +243,14 @@ always @ (*) begin
|
||||||
RV_DIVU: if (EXTENSION_M) begin d_aluop = ALUOP_MULDIV; d_mulop = M_OP_DIVU; end else begin d_invalid_32bit = 1'b1; end
|
RV_DIVU: if (EXTENSION_M) begin d_aluop = ALUOP_MULDIV; d_mulop = M_OP_DIVU; end else begin d_invalid_32bit = 1'b1; end
|
||||||
RV_REM: if (EXTENSION_M) begin d_aluop = ALUOP_MULDIV; d_mulop = M_OP_REM; end else begin d_invalid_32bit = 1'b1; end
|
RV_REM: if (EXTENSION_M) begin d_aluop = ALUOP_MULDIV; d_mulop = M_OP_REM; end else begin d_invalid_32bit = 1'b1; end
|
||||||
RV_REMU: if (EXTENSION_M) begin d_aluop = ALUOP_MULDIV; d_mulop = M_OP_REMU; end else begin d_invalid_32bit = 1'b1; end
|
RV_REMU: if (EXTENSION_M) begin d_aluop = ALUOP_MULDIV; d_mulop = M_OP_REMU; end else begin d_invalid_32bit = 1'b1; end
|
||||||
|
|
||||||
|
RV_LR_W: if (EXTENSION_A) begin d_imm = X0; d_alusrc_b = ALUSRCB_IMM; d_rs2 = X0; d_memop = MEMOP_LR_W; end
|
||||||
|
RV_SC_W: if (EXTENSION_A) begin d_imm = X0; d_alusrc_b = ALUSRCB_IMM; d_memop = MEMOP_SC_W; end
|
||||||
|
|
||||||
RV_SH1ADD: if (EXTENSION_ZBA) begin d_aluop = ALUOP_SH1ADD; end else begin d_invalid_32bit = 1'b1; end
|
RV_SH1ADD: if (EXTENSION_ZBA) begin d_aluop = ALUOP_SH1ADD; end else begin d_invalid_32bit = 1'b1; end
|
||||||
RV_SH2ADD: if (EXTENSION_ZBA) begin d_aluop = ALUOP_SH2ADD; end else begin d_invalid_32bit = 1'b1; end
|
RV_SH2ADD: if (EXTENSION_ZBA) begin d_aluop = ALUOP_SH2ADD; end else begin d_invalid_32bit = 1'b1; end
|
||||||
RV_SH3ADD: if (EXTENSION_ZBA) begin d_aluop = ALUOP_SH3ADD; end else begin d_invalid_32bit = 1'b1; end
|
RV_SH3ADD: if (EXTENSION_ZBA) begin d_aluop = ALUOP_SH3ADD; end else begin d_invalid_32bit = 1'b1; end
|
||||||
|
|
||||||
RV_ANDN: if (EXTENSION_ZBB) begin d_aluop = ALUOP_ANDN; end else begin d_invalid_32bit = 1'b1; end
|
RV_ANDN: if (EXTENSION_ZBB) begin d_aluop = ALUOP_ANDN; end else begin d_invalid_32bit = 1'b1; end
|
||||||
RV_CLZ: if (EXTENSION_ZBB) begin d_aluop = ALUOP_CLZ; d_rs2 = X0; end else begin d_invalid_32bit = 1'b1; end
|
RV_CLZ: if (EXTENSION_ZBB) begin d_aluop = ALUOP_CLZ; d_rs2 = X0; end else begin d_invalid_32bit = 1'b1; end
|
||||||
RV_CPOP: if (EXTENSION_ZBB) begin d_aluop = ALUOP_CPOP; d_rs2 = X0; end else begin d_invalid_32bit = 1'b1; end
|
RV_CPOP: if (EXTENSION_ZBB) begin d_aluop = ALUOP_CPOP; d_rs2 = X0; end else begin d_invalid_32bit = 1'b1; end
|
||||||
|
@ -263,6 +269,7 @@ always @ (*) begin
|
||||||
RV_SEXT_H: if (EXTENSION_ZBB) begin d_aluop = ALUOP_SEXT_H; d_rs2 = X0; end else begin d_invalid_32bit = 1'b1; end
|
RV_SEXT_H: if (EXTENSION_ZBB) begin d_aluop = ALUOP_SEXT_H; d_rs2 = X0; end else begin d_invalid_32bit = 1'b1; end
|
||||||
RV_XNOR: if (EXTENSION_ZBB) begin d_aluop = ALUOP_XNOR; end else begin d_invalid_32bit = 1'b1; end
|
RV_XNOR: if (EXTENSION_ZBB) begin d_aluop = ALUOP_XNOR; end else begin d_invalid_32bit = 1'b1; end
|
||||||
RV_ZEXT_H: if (EXTENSION_ZBB) begin d_aluop = ALUOP_ZEXT_H; d_rs2 = X0; end else begin d_invalid_32bit = 1'b1; end
|
RV_ZEXT_H: if (EXTENSION_ZBB) begin d_aluop = ALUOP_ZEXT_H; d_rs2 = X0; end else begin d_invalid_32bit = 1'b1; end
|
||||||
|
|
||||||
RV_CLMUL: if (EXTENSION_ZBC) begin d_aluop = ALUOP_CLMUL; end else begin d_invalid_32bit = 1'b1; end
|
RV_CLMUL: if (EXTENSION_ZBC) begin d_aluop = ALUOP_CLMUL; end else begin d_invalid_32bit = 1'b1; end
|
||||||
RV_CLMULH: if (EXTENSION_ZBC) begin d_aluop = ALUOP_CLMULH; end else begin d_invalid_32bit = 1'b1; end
|
RV_CLMULH: if (EXTENSION_ZBC) begin d_aluop = ALUOP_CLMULH; end else begin d_invalid_32bit = 1'b1; end
|
||||||
RV_CLMULR: if (EXTENSION_ZBC) begin d_aluop = ALUOP_CLMULR; end else begin d_invalid_32bit = 1'b1; end
|
RV_CLMULR: if (EXTENSION_ZBC) begin d_aluop = ALUOP_CLMULR; end else begin d_invalid_32bit = 1'b1; end
|
||||||
|
@ -274,6 +281,7 @@ always @ (*) begin
|
||||||
RV_BINVI: if (EXTENSION_ZBC) begin d_aluop = ALUOP_BINV; d_rs2 = X0; d_imm = d_imm_i; d_alusrc_b = ALUSRCB_IMM; end else begin d_invalid_32bit = 1'b1; end
|
RV_BINVI: if (EXTENSION_ZBC) begin d_aluop = ALUOP_BINV; d_rs2 = X0; d_imm = d_imm_i; d_alusrc_b = ALUSRCB_IMM; end else begin d_invalid_32bit = 1'b1; end
|
||||||
RV_BSET: if (EXTENSION_ZBC) begin d_aluop = ALUOP_BSET; end else begin d_invalid_32bit = 1'b1; end
|
RV_BSET: if (EXTENSION_ZBC) begin d_aluop = ALUOP_BSET; end else begin d_invalid_32bit = 1'b1; end
|
||||||
RV_BSETI: if (EXTENSION_ZBC) begin d_aluop = ALUOP_BSET; d_rs2 = X0; d_imm = d_imm_i; d_alusrc_b = ALUSRCB_IMM; end else begin d_invalid_32bit = 1'b1; end
|
RV_BSETI: if (EXTENSION_ZBC) begin d_aluop = ALUOP_BSET; d_rs2 = X0; d_imm = d_imm_i; d_alusrc_b = ALUSRCB_IMM; end else begin d_invalid_32bit = 1'b1; end
|
||||||
|
|
||||||
RV_FENCE: begin d_rd = X0; end // NOP
|
RV_FENCE: begin d_rd = X0; end // NOP
|
||||||
RV_FENCE_I: begin d_invalid_32bit = DEBUG_SUPPORT && debug_mode; d_rd = X0; d_rs1 = X0; d_rs2 = X0; d_branchcond = BCOND_NZERO; d_imm[31] = 1'b1; end // FIXME this is probably busted now. Maybe implement as an exception?
|
RV_FENCE_I: begin d_invalid_32bit = DEBUG_SUPPORT && debug_mode; d_rd = X0; d_rs1 = X0; d_rs2 = X0; d_branchcond = BCOND_NZERO; d_imm[31] = 1'b1; end // FIXME this is probably busted now. Maybe implement as an exception?
|
||||||
RV_CSRRW: if (HAVE_CSR) begin d_imm = d_imm_i; d_csr_wen = 1'b1 ; d_csr_ren = |d_rd; d_csr_wtype = CSR_WTYPE_W; end else begin d_invalid_32bit = 1'b1; end
|
RV_CSRRW: if (HAVE_CSR) begin d_imm = d_imm_i; d_csr_wen = 1'b1 ; d_csr_ren = |d_rd; d_csr_wtype = CSR_WTYPE_W; end else begin d_invalid_32bit = 1'b1; end
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
SRCS := ../common/init.S main.c
|
||||||
|
APP := lr_sc_smoke
|
||||||
|
CCFLAGS = -march=rv32imac -Os
|
||||||
|
|
||||||
|
include ../common/src_only_app.mk
|
|
@ -0,0 +1,43 @@
|
||||||
|
[*]
|
||||||
|
[*] GTKWave Analyzer v3.3.103 (w)1999-2019 BSI
|
||||||
|
[*] Sat Dec 4 14:31:51 2021
|
||||||
|
[*]
|
||||||
|
[dumpfile] "/home/luke/proj/hazard3/test/sim/lr_sc_smoke/lr_sc_smoke_run.vcd"
|
||||||
|
[dumpfile_mtime] "Sat Dec 4 14:20:04 2021"
|
||||||
|
[dumpfile_size] 2577335
|
||||||
|
[savefile] "/home/luke/proj/hazard3/test/sim/lr_sc_smoke/lr_sc_smoke.gtkw"
|
||||||
|
[timestart] 842
|
||||||
|
[size] 1975 1095
|
||||||
|
[pos] -1 -1
|
||||||
|
*-2.000000 856 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
|
||||||
|
[sst_width] 233
|
||||||
|
[signals_width] 246
|
||||||
|
[sst_expanded] 1
|
||||||
|
[sst_vpaned_height] 317
|
||||||
|
@22
|
||||||
|
core.d_pc[31:0]
|
||||||
|
@28
|
||||||
|
core.mw_local_exclusive_reserved
|
||||||
|
core.m_stall
|
||||||
|
core.x_stall
|
||||||
|
core.x_stall_raw
|
||||||
|
@200
|
||||||
|
-
|
||||||
|
@22
|
||||||
|
d_haddr[31:0]
|
||||||
|
@28
|
||||||
|
d_htrans[1:0]
|
||||||
|
d_hsize[2:0]
|
||||||
|
d_hexcl
|
||||||
|
d_hwrite
|
||||||
|
d_hready
|
||||||
|
@22
|
||||||
|
d_hwdata[31:0]
|
||||||
|
d_hrdata[31:0]
|
||||||
|
@200
|
||||||
|
-
|
||||||
|
@22
|
||||||
|
core.x_rs2_bypass[31:0]
|
||||||
|
core.xm_store_data[31:0]
|
||||||
|
[pattern_trace] 1
|
||||||
|
[pattern_trace] 0
|
|
@ -0,0 +1,65 @@
|
||||||
|
#include "tb_cxxrtl_io.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
volatile uint32_t scratch[2];
|
||||||
|
|
||||||
|
#define test_assert(cond, ...) if (!(cond)) {tb_printf(__VA_ARGS__); return -1;}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
uint32_t load_result, success;
|
||||||
|
tb_puts("Test 1: lr.w -> nop -> sc.w\n");
|
||||||
|
scratch[0] = 0x1234;
|
||||||
|
asm volatile (
|
||||||
|
"lr.w %0, (%2)\n"
|
||||||
|
"nop\n"
|
||||||
|
"sc.w %1, %3, (%2)\n"
|
||||||
|
: "=r" (load_result), "=r" (success)
|
||||||
|
: "r" (&scratch[0]), "r" (0x5678)
|
||||||
|
);
|
||||||
|
test_assert(load_result == 0x1234, "Bad load result %08x\n", load_result);
|
||||||
|
test_assert(scratch[0] == 0x5678, "Store didn't write memory\n");
|
||||||
|
test_assert(success == 1, "Should report success\n");
|
||||||
|
tb_puts("OK\n");
|
||||||
|
|
||||||
|
tb_puts("Test 2: lr.w -> sc.w\n");
|
||||||
|
scratch[0] = 0xabcd;
|
||||||
|
asm volatile (
|
||||||
|
"lr.w %0, (%2)\n"
|
||||||
|
"sc.w %1, %3, (%2)\n"
|
||||||
|
: "=r" (load_result), "=r" (success)
|
||||||
|
: "r" (&scratch[0]), "r" (0xa5a5)
|
||||||
|
);
|
||||||
|
test_assert(load_result == 0xabcd, "Bad load result %08x\n", load_result);
|
||||||
|
test_assert(scratch[0] == 0xa5a5, "Store didn't write memory\n");
|
||||||
|
test_assert(success == 1, "Should report success\n");
|
||||||
|
tb_puts("OK\n");
|
||||||
|
|
||||||
|
tb_puts("Test 3: sc.w with no preceding lr.w\n");
|
||||||
|
scratch[0] = 0x1234;
|
||||||
|
asm volatile (
|
||||||
|
"sc.w %0, %2, (%1)\n"
|
||||||
|
: "=r" (success)
|
||||||
|
: "r" (&scratch[0]), "r" (0x5678)
|
||||||
|
);
|
||||||
|
test_assert(scratch[0] == 0x1234, "Store shouldn't write memory\n");
|
||||||
|
test_assert(success == 0, "Should report failure\n");
|
||||||
|
tb_puts("OK\n");
|
||||||
|
|
||||||
|
// Reservation is only cleared by other harts' stores.
|
||||||
|
tb_puts("Test 4: lr.w -> sw -> sc.w\n");
|
||||||
|
scratch[0] = 0x1234;
|
||||||
|
scratch[1] = 0;
|
||||||
|
asm volatile (
|
||||||
|
"lr.w %0, (%2)\n"
|
||||||
|
"sw %3, 4(%2)\n"
|
||||||
|
"sc.w %1, %4, (%2)\n"
|
||||||
|
: "=r" (load_result), "=r" (success)
|
||||||
|
: "r" (&scratch[0]), "r" (0xabcd), "r" (0x5678)
|
||||||
|
);
|
||||||
|
test_assert(scratch[1] == 0xabcd, "Regular store should succeed\n");
|
||||||
|
test_assert(scratch[0] == 0x5678, "sc didn't write memory\n");
|
||||||
|
test_assert(success == 1, "Should report success\n");
|
||||||
|
tb_puts("OK\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -153,6 +153,7 @@ int main(int argc, char **argv) {
|
||||||
// Never generate bus stalls
|
// Never generate bus stalls
|
||||||
top.p_i__hready.set<bool>(true);
|
top.p_i__hready.set<bool>(true);
|
||||||
top.p_d__hready.set<bool>(true);
|
top.p_d__hready.set<bool>(true);
|
||||||
|
top.p_d__hexokay.set<bool>(true);
|
||||||
|
|
||||||
uint64_t mtime = 0;
|
uint64_t mtime = 0;
|
||||||
uint64_t mtimecmp = 0;
|
uint64_t mtimecmp = 0;
|
||||||
|
|
|
@ -36,12 +36,14 @@ module tb #(
|
||||||
output wire [W_ADDR-1:0] d_haddr,
|
output wire [W_ADDR-1:0] d_haddr,
|
||||||
output wire d_hwrite,
|
output wire d_hwrite,
|
||||||
output wire [1:0] d_htrans,
|
output wire [1:0] d_htrans,
|
||||||
|
output wire d_hexcl,
|
||||||
output wire [2:0] d_hsize,
|
output wire [2:0] d_hsize,
|
||||||
output wire [2:0] d_hburst,
|
output wire [2:0] d_hburst,
|
||||||
output wire [3:0] d_hprot,
|
output wire [3:0] d_hprot,
|
||||||
output wire d_hmastlock,
|
output wire d_hmastlock,
|
||||||
input wire d_hready,
|
input wire d_hready,
|
||||||
input wire d_hresp,
|
input wire d_hresp,
|
||||||
|
input wire d_hexokay,
|
||||||
output wire [W_DATA-1:0] d_hwdata,
|
output wire [W_DATA-1:0] d_hwdata,
|
||||||
input wire [W_DATA-1:0] d_hrdata,
|
input wire [W_DATA-1:0] d_hrdata,
|
||||||
|
|
||||||
|
@ -213,6 +215,7 @@ hazard3_cpu_2port #(
|
||||||
.i_hrdata (i_hrdata),
|
.i_hrdata (i_hrdata),
|
||||||
|
|
||||||
.d_haddr (d_haddr),
|
.d_haddr (d_haddr),
|
||||||
|
.d_hexcl (d_hexcl),
|
||||||
.d_hwrite (d_hwrite),
|
.d_hwrite (d_hwrite),
|
||||||
.d_htrans (d_htrans),
|
.d_htrans (d_htrans),
|
||||||
.d_hsize (d_hsize),
|
.d_hsize (d_hsize),
|
||||||
|
@ -221,6 +224,7 @@ hazard3_cpu_2port #(
|
||||||
.d_hmastlock (d_hmastlock),
|
.d_hmastlock (d_hmastlock),
|
||||||
.d_hready (d_hready),
|
.d_hready (d_hready),
|
||||||
.d_hresp (d_hresp),
|
.d_hresp (d_hresp),
|
||||||
|
.d_hexokay (d_hexokay),
|
||||||
.d_hwdata (d_hwdata),
|
.d_hwdata (d_hwdata),
|
||||||
.d_hrdata (d_hrdata),
|
.d_hrdata (d_hrdata),
|
||||||
|
|
||||||
|
|
|
@ -115,8 +115,10 @@ int main(int argc, char **argv) {
|
||||||
#ifdef DUAL_PORT
|
#ifdef DUAL_PORT
|
||||||
top.p_i__hready.set<bool>(true);
|
top.p_i__hready.set<bool>(true);
|
||||||
top.p_d__hready.set<bool>(true);
|
top.p_d__hready.set<bool>(true);
|
||||||
|
top.p_d__hexokay.set<bool>(true);
|
||||||
#else
|
#else
|
||||||
top.p_ahblm__hready.set<bool>(true);
|
top.p_ahblm__hready.set<bool>(true);
|
||||||
|
top.p_ahblm__hexokay.set<bool>(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint64_t mtime = 0;
|
uint64_t mtime = 0;
|
||||||
|
|
Loading…
Reference in New Issue