Encoding working

This commit is contained in:
Florian Zaruba 2018-09-21 13:01:21 +02:00
parent ea76d459fd
commit 3b75716a59
No known key found for this signature in database
GPG key ID: E742FFE8EC38A792
12 changed files with 182 additions and 61 deletions

View file

@ -2,7 +2,7 @@
# Ariane RISC-V CPU
Ariane is a 6-stage, single issue, in-order CPU which implements the 64-bit RISC-V instruction set. It fully implements I, M and C extensions as specified in Volume I: User-Level ISA V 2.1 as well as the draft privilege extension 1.10. It implements three privilege levels M, S, U to fully support a Unix-like operating system. Furthermore it is compliant to the draft external debug spec 0.13.
Ariane is a 6-stage, single issue, in-order CPU which implements the 64-bit RISC-V instruction set. It fully implements I, M, A and C extensions as specified in Volume I: User-Level ISA V 2.1 as well as the draft privilege extension 1.10. It implements three privilege levels M, S, U to fully support a Unix-like operating system. Furthermore it is compliant to the draft external debug spec 0.13.
It has configurable size, separate TLBs, a hardware PTW and branch-prediction (branch target buffer and branch history table). The primary design goal was on reducing critical path length.
@ -92,16 +92,16 @@ If you call `simc` instead of `sim` it will run without the GUI. QuestaSim uses
### CI Testsuites and Randomized Constrained Testing with Torture
We provide two CI configuration files for Travis CI and GitLab CI that run the RISCV assembly tests, the RISCV benchmarks and a randomized RISCV Torture test. The difference between the two is that Travis CI runs these tests only on Verilator, whereas GitLab CI runs the same tests on QuestaSim and Verilator.
We provide two CI configuration files for Travis CI and GitLab CI that run the RISCV assembly tests, the RISCV benchmarks and a randomized RISCV Torture test. The difference between the two is that Travis CI runs these tests only on Verilator, whereas GitLab CI runs the same tests on QuestaSim and Verilator.
If you would like to run the CI test suites locally on your machine, follow any of the two scripts `ci.travis-ci-emul.sh` and `ci.travis-ci-emul.sh` (depending on whether you have QuestaSim or not). In particular, you have to get the required packages for your system, the paths in `ci/path-setup.sh` to match your setup, and run the installation and build scripts prior to running any of the tests suites.
If you would like to run the CI test suites locally on your machine, follow any of the two scripts `ci.travis-ci-emul.sh` and `ci.travis-ci-emul.sh` (depending on whether you have QuestaSim or not). In particular, you have to get the required packages for your system, the paths in `ci/path-setup.sh` to match your setup, and run the installation and build scripts prior to running any of the tests suites.
Once everything is set up and installed, you can run the tests suites as follows (using Verilator):
```
$ make verilate
$ make run-asm-tests-verilator
$ make run-benchmarks-verilator
$ make verilate
$ make run-asm-tests-verilator
$ make run-benchmarks-verilator
```
In order to run randomized Torture tests, you first have to generate the randomized program prior to running the simulation:
@ -111,7 +111,7 @@ $ make torture-gen
$ make torture-rtest-verilator
```
This runs the randomized program on Spike and on the RTL target, and checks whether the two signatures match. The random instruction mix can be configured in the `./tmp/riscv-torture/config/default.config` file.
This runs the randomized program on Spike and on the RTL target, and checks whether the two signatures match. The random instruction mix can be configured in the `./tmp/riscv-torture/config/default.config` file.
# Contributing

View file

@ -32,7 +32,9 @@ package ariane_pkg;
localparam BITS_SATURATION_COUNTER = 2;
localparam NR_COMMIT_PORTS = 2;
localparam logic [63:0] ISA_CODE = (1 << 2) // C - Compressed extension
localparam logic [63:0] ISA_CODE =
| (1 << 0) // A - Atomic extension
| (1 << 2) // C - Compressed extension
| (1 << 8) // I - RV32I/64I/128I base ISA
| (1 << 12) // M - Integer Multiply/Divide extension
| (0 << 13) // N - User level interrupts supported
@ -218,7 +220,7 @@ package ariane_pkg;
endcase
endfunction
function automatic logic is_amo_op (fu_op op);
function automatic logic is_amo (fu_op op);
case (op)
AMO_LRD, AMO_SCD,
AMO_SWAPD, AMO_ADDD,

82
src/amo_buffer.sv Normal file
View file

@ -0,0 +1,82 @@
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
//
// Author: Florian Zaruba, ETH Zurich
// Date: 20.09.2018
// Description: Buffers AMO requests
// This unit buffers an atomic memory operations for the cache subsyste.
// Furthermore it handles interfacing with the commit stage
module amo_buffer (
input logic clk_i, // Clock
input logic rst_ni, // Asynchronous reset active low
input logic flush_i, // pipeline flush
input logic valid_i, // AMO is valid
output logic ready_o, // AMO unit is ready
input ariane_pkg::amo_t amo_op_i, // AMO Operation
input logic [63:0] paddr_i, // physical address of store which needs to be placed in the queue
input logic [63:0] data_i, // data which is placed in the queue
input logic [1:0] data_size_i, // type of request we are making (e.g.: bytes to write)
// D$
output ariane_pkg::amo_req_t amo_req_o, // request to cache subsytem
input ariane_pkg::amo_resp_t amo_resp_i, // response from cache subsystem
// Auxiliary signals
input logic amo_valid_commit_i, // We have a vaild AMO in the commit stage
input logic no_st_pending_i // there is currently no store pending anymore
);
logic flush_amo_buffer;
typedef struct packed {
ariane_pkg::amo_t op;
logic [63:0] paddr;
logic [63:0] data;
logic [1:0] size;
} amo_op_t ;
amo_op_t amo_data_in, amo_data_out;
// validate this request as soon as all stores have drained and the AMO is in the commit stage
assign amo_req_o.req = no_st_pending_i & amo_valid_commit_i;
assign amo_req_o.amo_op = amo_data_out.op;
assign amo_req_o.size = amo_data_out.size;
assign amo_req_o.operand_a = amo_data_out.paddr;
assign amo_req_o.operand_b = amo_data_out.data;
assign amo_data_in.op = amo_op_i;
assign amo_data_in.data = data_i;
assign amo_data_in.paddr = paddr_i;
assign amo_data_in.size = data_size_i;
// only flush if we are currently not committing the AMO
// e.g.: it is not speculative anymore
assign flush_amo_buffer = flush_i & !amo_valid_commit_i;
fifo_v2 #(
.DEPTH ( 1 ),
.ALM_EMPTY_TH ( 0 ),
.ALM_FULL_TH ( 0 ),
.dtype ( amo_op_t )
) i_amo_fifo (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.flush_i ( flush_amo_buffer ),
.testmode_i ( 1'b0 ),
.full_o ( ), // not used as this FIFO has only a single element depth
.empty_o ( ready_o ),
.alm_full_o ( ), // left open
.alm_empty_o ( ), // left open
.data_i ( amo_data_in ),
.push_i ( valid_i ),
.data_o ( amo_data_out ),
.pop_i ( amo_resp_i.ack )
);
endmodule

View file

@ -129,6 +129,7 @@ module ariane #(
logic lsu_commit_commit_ex;
logic lsu_commit_ready_ex_commit;
logic no_st_pending_ex_commit;
logic amo_valid_commit;
// --------------
// ID <-> COMMIT
// --------------
@ -196,6 +197,14 @@ module ariane #(
icache_areq_o_t icache_areq_cache_ex;
icache_dreq_i_t icache_dreq_if_cache;
icache_dreq_o_t icache_dreq_cache_if;
amo_req_t amo_req;
amo_resp_t amo_resp;
logic debug_req;
// Disable debug during AMO commit
assign debug_req = debug_req_i & ~amo_valid_commit;
// ----------------
// DCache <-> *
// ----------------
@ -344,6 +353,9 @@ module ariane #(
.lsu_commit_ready_o ( lsu_commit_ready_ex_commit ), // to commit
.lsu_exception_o ( lsu_exception_ex_id ),
.no_st_pending_o ( no_st_pending_ex_commit ),
.amo_valid_commit_i ( amo_valid_commit ),
.amo_req_o ( amo_req ),
.amo_resp_i ( amo_resp ),
// CSR
.csr_ready_o ( csr_ready_ex_id ),
.csr_valid_i ( csr_valid_id_ex ),
@ -389,7 +401,7 @@ module ariane #(
.flush_dcache_i ( dcache_flush_ctrl_cache ),
.exception_o ( ex_commit ),
.debug_mode_i ( debug_mode_csr_id ),
.debug_req_i ( debug_req_i ),
.debug_req_i ( debug_req ),
.single_step_i ( single_step_csr_commit ),
.commit_instr_i ( commit_instr_id_commit ),
.commit_ack_o ( commit_ack ),
@ -397,11 +409,10 @@ module ariane #(
.waddr_o ( waddr_commit_id ),
.wdata_o ( wdata_commit_id ),
.we_o ( we_commit_id ),
.amo_commit_o ( ),
.amo_valid_i ( ),
.amo_sc_succ_i ( ),
.commit_lsu_o ( lsu_commit_commit_ex ),
.commit_lsu_ready_i ( lsu_commit_ready_ex_commit ),
.amo_valid_commit_o ( amo_valid_commit ),
.amo_resp_i ( amo_resp ),
.commit_csr_o ( csr_commit_commit_ex ),
.pc_o ( pc_commit ),
.csr_op_o ( csr_op_commit_csr ),
@ -422,8 +433,8 @@ module ariane #(
) csr_regfile_i (
.flush_o ( flush_csr_ctrl ),
.halt_csr_o ( halt_csr_ctrl ),
.commit_ack_i ( commit_ack ),
.commit_instr_i ( commit_instr_id_commit ),
.commit_ack_i ( commit_ack ),
.ex_i ( ex_commit ),
.csr_op_i ( csr_op_commit_csr ),
.csr_addr_i ( csr_addr_ex_csr ),
@ -454,6 +465,10 @@ module ariane #(
.perf_data_o ( data_csr_perf ),
.perf_data_i ( data_perf_csr ),
.perf_we_o ( we_csr_perf ),
.debug_req_i ( debug_req ),
.ipi_i,
.irq_i,
.time_irq_i,
.*
);
@ -531,10 +546,8 @@ module ariane #(
.dcache_flush_i ( dcache_flush_ctrl_cache ),
.dcache_flush_ack_o ( dcache_flush_ack_cache_ctrl ),
// to commit stage
.dcache_amo_commit_i ( amo_commit ),
.dcache_amo_valid_o ( amo_valid ),
.dcache_amo_sc_succ_o ( amo_sc_succ ),
.dcache_amo_flush_i ( amo_flush ),
.amo_req_i ( amo_req ),
.amo_resp_o ( amo_resp ),
.dcache_miss_o ( dcache_miss_cache_perf ),
// from PTW, Load Unit and Store Unit
.dcache_req_ports_i ( dcache_req_ports_ex_cache ),

View file

@ -36,6 +36,8 @@ module std_nbdcache #(
AXI_BUS.Master bypass_if
);
assign amo_resp_o = '0;
// -------------------------------
// Controller <-> Arbiter
// -------------------------------

View file

@ -45,6 +45,7 @@ module commit_stage #(
// commit signals to ex
output logic commit_lsu_o, // commit the pending store
input logic commit_lsu_ready_i, // commit buffer of LSU is ready
output logic amo_valid_commit_o, // valid AMO in commit stage
input logic no_st_pending_i, // there is no store pending
output logic commit_csr_o, // commit the pending CSR instruction
output logic fence_i_o, // flush I$ and pipeline
@ -52,6 +53,9 @@ module commit_stage #(
output logic sfence_vma_o // flush TLBs and pipeline
);
assign waddr_o[0] = commit_instr_i[0].rd[4:0];
assign waddr_o[1] = commit_instr_i[1].rd[4:0];
assign pc_o = commit_instr_i[0].pc;
// -------------------
@ -63,6 +67,8 @@ module commit_stage #(
commit_ack_o[0] = 1'b0;
commit_ack_o[1] = 1'b0;
amo_valid_commit_o = 1'b0;
we_o[0] = 1'b0;
we_o[1] = 1'b0;
@ -145,6 +151,14 @@ module commit_stage #(
// tell the controller to flush the D$
fence_o = no_st_pending_i;
end
// ------------------
// AMO
// ------------------
if (is_amo(commit_instr_i[0].op)) begin
// TODO(zarubaf): Flush pipeline
amo_valid_commit_o = 1'b1;
commit_ack_o[0] = amo_resp_i.ack;
end
end
// -----------------
@ -210,8 +224,10 @@ module commit_stage #(
exception_o.tval = commit_instr_i[0].ex.tval;
end
end
// If we halted the processor don't take any exceptions
if (halt_i) begin
// Don't take any exceptions iff:
// - If we halted the processor
// - We are committing an AMO
if (halt_i || amo_valid_commit_o) begin
exception_o.valid = 1'b0;
end
end

View file

@ -126,7 +126,6 @@ module controller (
flush_if_o = 1'b1;
flush_unissued_instr_o = 1'b1;
flush_id_o = 1'b1;
flush_ex_o = 1'b1;
end

View file

@ -105,9 +105,9 @@ module csr_regfile #(
riscv::status_rv64_t mstatus_q, mstatus_d;
riscv::satp_t satp_q, satp_d;
riscv::dcsr_t dcsr_q, dcsr_d;
logic mtvec_rst_load_q;// used to determine whether we came out of reset
logic [63:0] dpc_q, dpc_d;
logic [63:0] dscratch0_q, dscratch0_d;
logic [63:0] mtvec_q, mtvec_d;
@ -245,16 +245,16 @@ module csr_regfile #(
dpc_d = dpc_q;
dscratch0_d = dscratch0_q;
mstatus_d = mstatus_q;
// check whether we come out of reset
// this is a workaround. some tools have issues
// having boot_addr_i in the asynchronous
// this is a workaround. some tools have issues
// having boot_addr_i in the asynchronous
// reset assignment to mtvec_d, even though
// boot_addr_i will be assigned a constant
// on the top-level.
// on the top-level.
if (mtvec_rst_load_q) begin
mtvec_d = boot_addr_i + 'h40;
end else begin
end else begin
mtvec_d = mtvec_q;
end
@ -525,6 +525,7 @@ module csr_regfile #(
end
// we've got a debug request (and we have an instruction which we can associate it to)
// don't interrupt the AMO
if (debug_req_i && commit_instr_i[0].valid) begin
// save the PC
dpc_d = pc_i;

View file

@ -58,6 +58,7 @@ module ex_stage #(
output logic lsu_commit_ready_o, // commit queue is ready to accept another commit request
output exception_t lsu_exception_o,
output logic no_st_pending_o,
input logic amo_valid_commit_i,
// CSR
output logic csr_ready_o,
input logic csr_valid_i,
@ -91,7 +92,8 @@ module ex_stage #(
// interface to dcache
input dcache_req_o_t [2:0] dcache_req_ports_i,
output dcache_req_i_t [2:0] dcache_req_ports_o,
output amo_req_t amo_req_o, // request to cache subsytem
input amo_resp_t amo_resp_i, // response from cache subsystem
// Performance counters
output logic itlb_miss_o,
output logic dtlb_miss_o
@ -131,8 +133,10 @@ module ex_stage #(
lsu lsu_i (
.commit_i ( lsu_commit_i ),
.commit_ready_o ( lsu_commit_ready_o ),
.dcache_req_ports_i ( dcache_req_ports_i ),
.dcache_req_ports_o ( dcache_req_ports_o ),
.dcache_req_ports_i,
.dcache_req_ports_o,
.amo_req_o,
.amo_resp_i,
.*
);

View file

@ -15,12 +15,13 @@
import ariane_pkg::*;
module lsu #(
parameter int unsigned ASID_WIDTH = 1
parameter int unsigned ASID_WIDTH = 1
)(
input logic clk_i,
input logic rst_ni,
input logic flush_i,
output logic no_st_pending_o,
input logic amo_valid_commit_i,
input fu_t fu_i,
input fu_op operator_i,
@ -59,6 +60,7 @@ module lsu #(
output dcache_req_i_t [2:0] dcache_req_ports_o,
// AMO interface
output amo_req_t amo_req_o,
input amo_resp_t amo_resp_i,
output exception_t lsu_exception_o // to WB, signal exception status LD/ST exception
);
@ -139,9 +141,17 @@ module lsu #(
// Store Unit
// ------------------
store_unit i_store_unit (
.clk_i,
.rst_ni,
.flush_i,
.no_st_pending_o,
.valid_i ( st_valid_i ),
.lsu_ctrl_i ( lsu_ctrl ),
.pop_st_o ( pop_st ),
.commit_i,
.commit_ready_o,
.amo_valid_commit_i,
.valid_o ( st_valid ),
.trans_id_o ( st_trans_id ),
@ -156,10 +166,12 @@ module lsu #(
// Load Unit
.page_offset_i ( page_offset ),
.page_offset_matches_o ( page_offset_matches ),
// AMOs
.amo_req_o,
.amo_resp_i,
// to memory arbiter
.req_port_i ( dcache_req_ports_i [2] ),
.req_port_o ( dcache_req_ports_o [2] ),
.*
.req_port_o ( dcache_req_ports_o [2] )
);
// ------------------
@ -253,11 +265,7 @@ module lsu #(
LD, SD: begin // double word
be_i = 8'b1111_1111;
end
LW, LWU, SW,
AMO_LRW, AMO_SCW,
AMO_SWAPW, AMO_ADDW, AMO_ANDW, AMO_ORW,
AMO_XORW, AMO_MAXW, AMO_MAXWU, AMO_MINW,
AMO_MINWU: begin// word
LW, LWU, SW: begin// word
case (vaddr_i[2:0])
3'b000: be_i = 8'b0000_1111;
3'b001: be_i = 8'b0001_1110;
@ -348,7 +356,7 @@ module lsu #(
if (data_misaligned) begin
if (lsu_ctrl.fu == LOAD || lsu_ctrl.fu == AMO) begin
if (lsu_ctrl.fu == LOAD) begin
misaligned_exception = {
riscv::LD_ADDR_MISALIGNED,
lsu_ctrl.vaddr,
@ -402,15 +410,6 @@ module lsu #(
.ready_o ( lsu_ready_o ),
.*
);
// ------------
// Assertions
// ------------
`ifndef SYNTHESIS
`ifndef VERILATOR
// TODO
`endif
`endif
endmodule
// ------------------

View file

@ -62,9 +62,11 @@ module store_unit (
logic st_valid_without_flush;
// keep the data and the byte enable for the second cycle (after address translation)
logic [63:0] st_data_n, st_data_q;
logic [7:0] st_be_n, st_be_q;
logic [1:0] st_data_size_n, st_data_size_q;
logic [63:0] st_data_n, st_data_q;
logic [7:0] st_be_n, st_be_q;
logic [1:0] st_data_size_n, st_data_size_q;
amo_t amo_op_d, amo_op_q;
logic [TRANS_ID_BITS-1:0] trans_id_n, trans_id_q;
// output assignments
@ -193,11 +195,14 @@ module store_unit (
end
logic store_buffer_valid, amo_buffer_valid;
logic store_buffer_ready, amo_buffer_ready;
// multiplex between store unit and amo buffer
assign store_buffer_valid = st_valid & (amo_op_q == AMO_NONE);
assign amo_buffer_valid = st_valid & (amo_op_q != AMO_NONE);
assign st_ready = store_buffer_ready & amo_buffer_ready;
// ---------------
// Store Queue
// ---------------
@ -210,7 +215,7 @@ module store_unit (
.page_offset_matches_o,
.commit_i,
.commit_ready_o,
.ready_o ( st_ready ),
.ready_o ( store_buffer_ready ),
.valid_i ( store_buffer_valid ),
// the flush signal can be critical and we need this valid
// signal to check whether the page_offset matches or not,
@ -229,8 +234,6 @@ module store_unit (
// ---------------
// AMO Buffer
// ---------------
amo_t amo_op_q, amo_op_q;
always_comb begin
amo_op_d = amo_op_q;
@ -250,11 +253,11 @@ module store_unit (
end
amo_buffer i_amo_buffer (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.flush_i ( flush_i ),
.clk_i,
.rst_ni,
.flush_i,
.valid_i ( amo_buffer_valid ),
.ready_o ( commit_ready_o ),
.ready_o ( amo_buffer_ready ),
.paddr_i ( paddr_i ),
.amo_op_i ( amo_op_q ),
.data_i ( st_data_q ),

View file

@ -397,7 +397,7 @@ class instruction_trace_item;
5'h14: mnemonic = "amomax.w";
5'h18: mnemonic = "amominu.w";
5'h1C: mnemonic = "amomax.w";
default: printMnemonic("INVALID");
default: return printMnemonic("INVALID");
endcase
end if (instr[14:12] == 3'h3) begin
// doubles
@ -413,7 +413,7 @@ class instruction_trace_item;
5'h14: mnemonic = "amomax.d";
5'h18: mnemonic = "amominu.d";
5'h1C: mnemonic = "amomax.d";
default: printMnemonic("INVALID");
default: return printMnemonic("INVALID");
endcase
end else return printMnemonic("INVALID");