data/full_repos/permissive/194920488/rvfi_monitor.v
 line:398 column:31: Illegal character "'"
1: b'%Warning-STMTDLY: data/full_repos/permissive/194920488/rvfi_monitor.v:684: Unsupported: Ignoring delay on this delayed statement.\n        #1;   \n        ^\n                  ... Use "/* verilator lint_off STMTDLY */" and lint_on around source to disable this message.\n%Warning-IMPLICIT: data/full_repos/permissive/194920488/rvfi_monitor.v:177: Signal definition not found, creating implicitly: \'expect_insn_complete\'\n pc <= reset ? PROGADDR_RESET : ( expect_insn_complete ? expect_pc_next : pc ) ;\n                                  ^~~~~~~~~~~~~~~~~~~~\n%Warning-IMPLICIT: data/full_repos/permissive/194920488/rvfi_monitor.v:292: Signal definition not found, creating implicitly: \'insn_addr\'\n assign insn_addr = { pc[31:1], 1\'b0 };\n        ^~~~~~~~~\n%Warning-IMPLICIT: data/full_repos/permissive/194920488/rvfi_monitor.v:703: Signal definition not found, creating implicitly: \'expect_rd_addr_valid\'\n                                                                          : ... Suggested alternative: \'expect_rd_addr\'\n     if ( expect_rd_addr_valid ) begin\n          ^~~~~~~~~~~~~~~~~~~~\n%Warning-IMPLICIT: data/full_repos/permissive/194920488/rvfi_monitor.v:710: Signal definition not found, creating implicitly: \'expect_rs1_addr_valid\'\n                                                                          : ... Suggested alternative: \'expect_rd_addr_valid\'\n     if ( expect_rs1_addr_valid ) begin\n          ^~~~~~~~~~~~~~~~~~~~~\n%Warning-IMPLICIT: data/full_repos/permissive/194920488/rvfi_monitor.v:717: Signal definition not found, creating implicitly: \'expect_rs2_addr_valid\'\n                                                                          : ... Suggested alternative: \'expect_rs1_addr_valid\'\n     if ( expect_rs2_addr_valid ) begin\n          ^~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/194920488/rvfi_monitor.v:208: Cannot find file containing module: \'comb_rv32\'\ncomb_rv32 comb_rv32 (\n^~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/194920488,data/full_repos/permissive/194920488/comb_rv32\n             data/full_repos/permissive/194920488,data/full_repos/permissive/194920488/comb_rv32.v\n             data/full_repos/permissive/194920488,data/full_repos/permissive/194920488/comb_rv32.sv\n             comb_rv32\n             comb_rv32.v\n             comb_rv32.sv\n             obj_dir/comb_rv32\n             obj_dir/comb_rv32.v\n             obj_dir/comb_rv32.sv\n%Warning-WIDTH: data/full_repos/permissive/194920488/rvfi_monitor.v:292: Operator ASSIGNW expects 1 bits on the Assign RHS, but Assign RHS\'s REPLICATE generates 32 bits.\n                                                                       : ... In instance rvfi_monitor\n assign insn_addr = { pc[31:1], 1\'b0 };\n                  ^\n%Warning-WIDTH: data/full_repos/permissive/194920488/rvfi_monitor.v:350: Operator ADD expects 32 bits on the LHS, but LHS\'s VARREF \'insn_addr\' generates 1 bits.\n                                                                       : ... In instance rvfi_monitor\n wire [31:0] pc_next_no_branch = insn_addr + 4;\n                                           ^\n%Warning-WIDTH: data/full_repos/permissive/194920488/rvfi_monitor.v:351: Operator ADD expects 32 bits on the LHS, but LHS\'s VARREF \'insn_addr\' generates 1 bits.\n                                                                       : ... In instance rvfi_monitor\n wire [31:0] pc_next_branch = ( insn_addr + immediate_for_branches ) & 32\'hFFFF_FFFE;\n                                          ^\n%Warning-WIDTH: data/full_repos/permissive/194920488/rvfi_monitor.v:354: Operator ASSIGNW expects 257 bits on the Assign RHS, but Assign RHS\'s CONST \'256\'h42474555424c545542474520424c54202020202020202020424e452042455120\' generates 256 bits.\n                                                                       : ... In instance rvfi_monitor\nwire [8*4*8:0] branch_mnemonics = "BGEUBLTUBGE BLT         BNE BEQ ";\n                                ^\n%Warning-WIDTH: data/full_repos/permissive/194920488/rvfi_monitor.v:404: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS\'s SEL generates 20 bits.\n                                                                       : ... In instance rvfi_monitor\n    immediate = insn[31:12];\n              ^\n%Warning-WIDTH: data/full_repos/permissive/194920488/rvfi_monitor.v:412: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS\'s SEL generates 20 bits.\n                                                                       : ... In instance rvfi_monitor\n    immediate = insn[31:12];\n              ^\n%Warning-WIDTH: data/full_repos/permissive/194920488/rvfi_monitor.v:448: Operator ASSIGN expects 40 bits on the Assign RHS, but Assign RHS\'s SEL generates 32 bits.\n                                                                       : ... In instance rvfi_monitor\n     mnemonic = branch_mnemonics[ 4*8*insn_field_funct3 +: 4*8];\n              ^\n%Warning-WIDTH: data/full_repos/permissive/194920488/rvfi_monitor.v:670: Operator ASSIGN expects 769 bits on the Assign RHS, but Assign RHS\'s REPLICATE generates 768 bits.\n                                                                       : ... In instance rvfi_monitor\n reg [32*3*8:0] register_names  = {\n                                  ^\n%Error: Exiting due to 1 error(s), 14 warning(s)\n        ... See the manual and https://verilator.org for more assistance.\n'
module rvfi_monitor (


    input          clk,
    input          reset,

	input          rvfi_valid,
	input   [63:0] rvfi_order,
	input   [31:0] rvfi_insn,
	input          rvfi_trap,
	input          rvfi_halt,
	input          rvfi_intr,
	input   [ 1:0] rvfi_mode,
	input   [ 1:0] rvfi_ixl,
	input   [ 4:0] rvfi_rs1_addr,
	input   [ 4:0] rvfi_rs2_addr,
	input   [31:0] rvfi_rs1_rdata,
	input   [31:0] rvfi_rs2_rdata,
	input   [ 4:0] rvfi_rd_addr,
	input   [31:0] rvfi_rd_wdata,
	input   [31:0] rvfi_pc_rdata,
	input   [31:0] rvfi_pc_wdata,

	input   [31:0] rvfi_mem_addr,
	input   [ 3:0] rvfi_mem_rmask,
	input   [ 3:0] rvfi_mem_wmask,
	input   [31:0] rvfi_mem_rdata,
	input   [31:0] rvfi_mem_wdata,

	input   [63:0] rvfi_csr_mcycle_rmask,
	input   [63:0] rvfi_csr_mcycle_wmask,
	input   [63:0] rvfi_csr_mcycle_rdata,
	input   [63:0] rvfi_csr_mcycle_wdata,

	input   [63:0] rvfi_csr_minstret_rmask,
	input   [63:0] rvfi_csr_minstret_wmask,
	input   [63:0] rvfi_csr_minstret_rdata,
	input   [63:0] rvfi_csr_minstret_wdata

);






wire             expect_rvfi_valid        ;
wire      [63:0] expect_rvfi_order        ;
wire      [31:0] expect_rvfi_insn         ;
wire             expect_rvfi_trap         ;
wire             expect_rvfi_halt         ;
wire             expect_rvfi_intr         ;
wire      [ 1:0] expect_rvfi_mode         ;
wire      [ 1:0] expect_rvfi_ixl          ;
wire      [ 4:0] expect_rvfi_rs1_addr     ;
wire      [ 4:0] expect_rvfi_rs2_addr     ;
wire      [31:0] expect_rvfi_rs1_rdata    ;
wire      [31:0] expect_rvfi_rs2_rdata    ;
wire      [ 4:0] expect_rvfi_rd_addr      ;
wire      [31:0] expect_rvfi_rd_wdata     ;
wire      [31:0] expect_rvfi_pc_rdata     ;
wire      [31:0] expect_rvfi_pc_wdata     ;
wire      [31:0] expect_rvfi_mem_addr     ;
wire      [ 3:0] expect_rvfi_mem_rmask    ;
wire      [ 3:0] expect_rvfi_mem_wmask    ; 
wire      [31:0] expect_rvfi_mem_rdata    ;
wire      [31:0] expect_rvfi_mem_wdata    ;
wire      [63:0] expect_rvfi_csr_mcycle_rmask      ;
wire      [63:0] expect_rvfi_csr_mcycle_wmask      ;
wire      [63:0] expect_rvfi_csr_mcycle_rdata      ;
wire      [63:0] expect_rvfi_csr_mcycle_wdata      ;
wire      [63:0] expect_rvfi_csr_minstret_rmask    ;
wire      [63:0] expect_rvfi_csr_minstret_wmask    ;
wire      [63:0] expect_rvfi_csr_minstret_rdata    ;
wire      [63:0] expect_rvfi_csr_minstret_wdata    ;

wire      [31:0] expect_pc_next                  ;
wire      [31:0] expect_insn_addr                ;
wire      [ 4:0] expect_rs1_addr                 ;
wire      [ 4:0] expect_rs2_addr                 ;
wire      [ 4:0] expect_rd_addr                 ;

wire             expect_rs1_request             ;
wire             expect_rs2_request             ;
wire             expect_rd_request              ;



wire      [31:0] shadow_rs1_rdata               ;
wire      [31:0] shadow_rs2_rdata               ;
wire      [31:0] expect_rd_wdata                ;

wire             expect_mem_valid               ;
wire             expect_mem_instr               ;
wire      [31:0] expect_mem_addr                ;
wire      [31:0] expect_mem_wdata               ;
wire      [ 3:0] expect_mem_wstrb               ;
wire      [ 3:0] expect_mem_rmask               ;

wire      [63:0] expect_csr_time                ;
wire      [63:0] expect_csr_cycle               ;
wire      [63:0] expect_csr_instret             ;



integer   fd;
initial begin
    fd = $fopen( "rvfi_mon.txt", "w" );
end

wire  insn_valid = 1 ;




reg [63:0]  csr_cycle;
reg [63:0]  csr_time;
reg [63:0]  csr_instret;

always @(posedge clk) begin
	if ( reset ) begin
		csr_cycle   <= 0 ;
		csr_time    <= 0 ; 
		csr_instret <= 0 ;
	end else begin
		csr_cycle   <= csr_cycle   + 1 ;
		csr_time    <= csr_time    + 1 ; 
		if (rvfi_valid) begin
            csr_instret <= csr_instret + 1 ;
        end
	end
end

integer instruction_cycles;
integer instruction_cycles_next;
always @(*) begin
	instruction_cycles_next = reset ? 0 : rvfi_valid ? 1 : (instruction_cycles+1) ; 
end
always @(posedge clk) begin
	instruction_cycles <= instruction_cycles_next;
end

localparam PROGADDR_RESET = 'h10000;
localparam STACKADDR      = 'h10000;



reg [31:0] pc;








initial pc = PROGADDR_RESET;
always @(posedge clk) begin
	pc <= reset ? PROGADDR_RESET : ( expect_insn_complete ? expect_pc_next : pc ) ;
end

integer i;
reg [31:0] registers [ 0:31 ];
always @(posedge clk) begin
	if ( reset ) begin
		registers[ 0] <= 0;
        registers[ 1] <= 32'hx;
		registers[ 2] <= STACKADDR;
        for( i=3; i <32; i=i+1 ) begin
            registers[i] <= 32'hx;
        end
	end
	if ( expect_rd_request ) begin
		registers[ expect_rd_addr ] <= expect_rd_wdata;
	end
end

assign shadow_rs1_rdata = expect_rs1_request ? registers[ expect_rs1_addr ] : 32'bx;
assign shadow_rs2_rdata = expect_rs2_request ? registers[ expect_rs2_addr ] : 32'bx;


wire [3:0] mem_wstrb;







comb_rv32 comb_rv32 (

	  .trap            ( expect_trap           )
	, .pc              ( rvfi_pc_rdata         )
	, .pc_next         ( expect_pc_next        )
	, .pc_next_valid   ( expect_pc_next_valid  )
	, .insn_addr       ( expect_insn_addr      )
	, .insn            ( rvfi_insn             )
	, .insn_valid      ( rvfi_valid            )
	, .insn_complete   ( expect_insn_complete  )
	, .rs1_addr        ( expect_rs1_addr       )
	, .rs2_addr        ( expect_rs2_addr       )
	, .rd_addr         ( expect_rd_addr        )
	, .rs1_addr_valid  ( expect_rs1_addr_valid )
	, .rs2_addr_valid  ( expect_rs2_addr_valid )
	, .rd_addr_valid   ( expect_rd_addr_valid  )

	, .rs1_request     ( expect_rs1_request           )
	, .rs2_request     ( expect_rs2_request           )
	, .rd_request      ( expect_rd_request            )

	, .rs1_rdata       ( shadow_rs1_rdata      )
	, .rs2_rdata       ( shadow_rs2_rdata      )
	, .rd_wdata        ( expect_rd_wdata       )
	, .rs1_ready       (             1'b1      )
	, .rs2_ready       (             1'b1      )
	, .rd_ready        (             1'b1      )
	, .mem_valid       ( expect_mem_valid      )
	, .mem_instr       ( expect_mem_instr      )
	, .mem_ready       (             1'b1      )
	, .mem_addr        ( expect_mem_addr       )
	, .mem_wdata       ( expect_mem_wdata      )
	, .mem_wstrb       ( expect_mem_wstrb      )
	, .mem_rmask       ( expect_mem_rmask      )
	, .mem_rdata       (   rvfi_mem_rdata      )
	, .csr_time        (        csr_time       )
	, .csr_cycle       (        csr_cycle      )
	, .csr_instret     (        csr_instret    )



	, .rvfi_valid              ( expect_rvfi_valid                  )
	, .rvfi_order              ( expect_rvfi_order                  )
	, .rvfi_insn               ( expect_rvfi_insn                   )
	, .rvfi_trap               ( expect_rvfi_trap                   )
	, .rvfi_halt               ( expect_rvfi_halt                   )
	, .rvfi_intr               ( expect_rvfi_intr                   )
	, .rvfi_mode               ( expect_rvfi_mode                   )
	, .rvfi_ixl                ( expect_rvfi_ixl                    )
	, .rvfi_rs1_addr           ( expect_rvfi_rs1_addr               )
	, .rvfi_rs2_addr           ( expect_rvfi_rs2_addr               )
	, .rvfi_rs1_rdata          ( expect_rvfi_rs1_rdata              )
	, .rvfi_rs2_rdata          ( expect_rvfi_rs2_rdata              )
	, .rvfi_rd_addr            ( expect_rvfi_rd_addr                )
	, .rvfi_rd_wdata           ( expect_rvfi_rd_wdata               )
	, .rvfi_pc_rdata           ( expect_rvfi_pc_rdata               )
	, .rvfi_pc_wdata           ( expect_rvfi_pc_wdata               )
	, .rvfi_mem_addr           ( expect_rvfi_mem_addr               )
	, .rvfi_mem_rmask          ( expect_rvfi_mem_rmask              )
	, .rvfi_mem_wmask          ( expect_rvfi_mem_wmask              )
	, .rvfi_mem_rdata          ( expect_rvfi_mem_rdata              )
	, .rvfi_mem_wdata          ( expect_rvfi_mem_wdata              )
	, .rvfi_csr_mcycle_rmask   ( expect_rvfi_csr_mcycle_rmask       )
	, .rvfi_csr_mcycle_wmask   ( expect_rvfi_csr_mcycle_wmask       )
	, .rvfi_csr_mcycle_rdata   ( expect_rvfi_csr_mcycle_rdata       )
	, .rvfi_csr_mcycle_wdata   ( expect_rvfi_csr_mcycle_wdata       )
	, .rvfi_csr_minstret_rmask ( expect_rvfi_csr_minstret_rmask     )
	, .rvfi_csr_minstret_wmask ( expect_rvfi_csr_minstret_wmask     )
	, .rvfi_csr_minstret_rdata ( expect_rvfi_csr_minstret_rdata     )
	, .rvfi_csr_minstret_wdata ( expect_rvfi_csr_minstret_wdata     )

);


reg  [5*8-1:0] mnemonic = "???";









	assign insn_addr = { pc[31:1], 1'b0 };



	reg insn_decode_valid;



	wire [31:0] insn = rvfi_insn;

	wire [6:0] insn_field_opcode = insn[6:0];
	wire [2:0] insn_field_funct3 = insn[14:12];
	wire [6:0] insn_field_funct7 = insn[31:25];
	wire [4:0] insn_field_rd     = insn[11:7];
	wire [4:0] insn_field_rs1    = insn[19:15];
	wire [4:0] insn_field_rs2    = insn[24:20];












	reg is_alu_immediate;

	wire [31:0] immediate_12bit = { {20{insn[31]}}, insn[31:20] };
	wire [31:0] immediate_12bit_for_stores = { immediate_12bit[31:5], insn[11:7] };
	wire [31:0] immediate_for_jal = { {12{insn[31]}}, insn[19:12], insn[20], insn[30:21], 1'b0 };
	wire [31:0] immediate_for_branches = { {20{insn[31]}}, insn[7], insn[ 30:25], insn[11:8], 1'b0 };

	wire [31:0] pc_next_no_branch = insn_addr + 4;
	wire [31:0] pc_next_branch = ( insn_addr + immediate_for_branches ) & 32'hFFFF_FFFE;


wire [8*4*8:0] branch_mnemonics = "BGEUBLTUBGE BLT         BNE BEQ ";







integer immediate;
reg     has_immediate;

reg     is_load;
reg     is_store;

	always @* begin









		is_alu_immediate = 0;
		mnemonic = "???";
		immediate = 0;
		has_immediate = 0;
		is_load = 0;
		is_store = 0;












		if ( insn_valid ) begin 

			if (insn_field_opcode == 7'b 01_101_11) begin
				insn_decode_valid = 1;
				mnemonic = "LUI";


				has_immediate = 1;
				immediate = insn[31:12];
			end
			if (insn_field_opcode == 7'b 00_101_11) begin
				insn_decode_valid = 1;
				mnemonic = "AUIPC";


				has_immediate = 1;
				immediate = insn[31:12];

			end
			if (insn_field_opcode == 7'b 11_011_11) begin
				insn_decode_valid = 1;
				mnemonic = "JAL";





				has_immediate = 1;
				immediate = immediate_for_jal;

			end
			if (insn_field_opcode == 7'b 11_001_11) begin
				if (  insn_field_funct3 == 3'b 000 ) begin
					insn_decode_valid = 1;
					mnemonic = "JALR";





					has_immediate = 1;
					immediate = immediate_12bit;

				end
			end

			if (insn_field_opcode == 7'b 11_000_11) begin
				insn_decode_valid = (insn_field_funct3 != 3'b 010) && (insn_field_funct3 != 3'b 011);



				if ( insn_decode_valid ) begin
					mnemonic = branch_mnemonics[ 4*8*insn_field_funct3 +: 4*8];
					has_immediate = 1;
					immediate = immediate_for_branches;









					end


			end

			if (insn_field_opcode == 7'b 00_000_11) begin
				insn_decode_valid = (insn_field_funct3 != 3'b 011) && (insn_field_funct3 != 3'b 110) && (insn_field_funct3 != 3'b 111);




					has_immediate = 1;
					immediate = immediate_12bit;
					is_load = 1;

				if (insn_field_funct3 == 3'b000 ) begin


					mnemonic = "LB";
				end
				if (insn_field_funct3 == 3'b100 ) begin


					mnemonic = "LBU";
				end
				if (insn_field_funct3 == 3'b001 ) begin


					mnemonic = "LH";
				end
				if (insn_field_funct3 == 3'b101 ) begin


					mnemonic = "LHU";
				end
				if (insn_field_funct3 == 3'b010 ) begin


					mnemonic = "LW";
				end
			end

			if (insn_field_opcode == 7'b 01_000_11) begin
				insn_decode_valid = (insn_field_funct3 == 3'b 000) || (insn_field_funct3 == 3'b 001) || (insn_field_funct3 == 3'b 010);






					has_immediate = 1;
					immediate = immediate_12bit_for_stores;
					is_store = 1;


				if (insn_field_funct3 == 3'b000 ) begin

					mnemonic = "SB";
				end
				if (insn_field_funct3 == 3'b001 ) begin

					mnemonic = "SH";
				end
				if (insn_field_funct3 == 3'b010 ) begin

					mnemonic = "SW";
				end

			end

			if ( (insn_field_opcode == 7'b 01_100_11) || (insn_field_opcode == 7'b 00_100_11) ) begin
				is_alu_immediate = (insn_field_opcode == 7'b 00_100_11);
				if ( is_alu_immediate ) begin

					has_immediate = 1;
					immediate = immediate_12bit;					
				end

				case (insn_field_funct3)
					3'b 000: begin




						if (is_alu_immediate || insn_field_funct7 == 7'b 0000000) begin
							insn_decode_valid = 1;

							mnemonic = has_immediate ? "ADDI" : "ADD";
						end else if ( insn_field_funct7 == 7'b 0100000 ) begin
							insn_decode_valid = 1;

							mnemonic = has_immediate ? "SUBI" : "SUB";						end
					end
					3'b 101: begin





						if ( insn_field_funct7 == 7'b 0000000 ) begin
							insn_decode_valid = 1;

							mnemonic = has_immediate ? "SRLI" : "SRL";
						end else if ( (!is_alu_immediate && insn_field_funct7 == 7'b 0100000 ) || ( is_alu_immediate && insn_field_funct7 == 7'b 0100000 ) ) begin
							insn_decode_valid = 1;
							mnemonic = has_immediate ? "SRAI" : "SRA";

						end
					end
					3'b001: begin 

						if ( insn_field_funct7 == 7'b 0000000 ) begin 
							insn_decode_valid = 1;




							mnemonic = is_alu_immediate ? "SLLI" : "SLL";

						end
					end
					default: begin
						if ( is_alu_immediate || insn_field_funct7 == 7'b 0000000 ) begin
							insn_decode_valid = 1;



							case (insn_field_funct3)



								3'b010: begin

									mnemonic = is_alu_immediate ? "SLTI" : "SLT";
								end
								3'b011: begin

									mnemonic = is_alu_immediate ? "SLTUI" : "SLTU";
								end
								3'b100: begin

									mnemonic = is_alu_immediate ? "XORI" : "XOR";
								end
								3'b110: begin

									mnemonic = is_alu_immediate ? "ORI" : "OR";
								end
								3'b111: begin

									mnemonic = is_alu_immediate ? "ANDI" : "AND";
								end
							endcase
						end
					end
				endcase
			end
			if (insn_field_opcode == 7'b 11_100_11) begin 
				if ( insn_field_rs1 == 0 && insn_field_funct3 == 3'b010 ) begin
					case (insn[31:20])
						12'hC00: begin
							insn_decode_valid = 1 ;


						end
						12'hC01: begin
							insn_decode_valid = 1 ;


						end
						12'hC02: begin
							insn_decode_valid = 1 ;


						end
						12'hC80: begin
							insn_decode_valid = 1 ;


						end
						12'hC81: begin
							insn_decode_valid = 1 ;


						end
						12'hC82: begin
							insn_decode_valid = 1 ;


						end
					endcase
					end
			end
		end
	end



wire mismatch = 0;





	reg [32*3*8:0] register_names  = {
		  " t6 t5 t4 t3s11s10 s9 s8"
		, " s7 s6 s5 s4 s3 s2 a7 a6"
		, " a5 a4 a3 a2 a1 a0 s1 fp"
		, " t2 t1 t0 tp gp sp ra 00"
	};







    always @(posedge clk) begin
        #1;



        if (reset ) begin
            $fdisplay( fd, "reset" );
        end else begin
            if (rvfi_valid) begin
				if ( insn_decode_valid ) begin 

	                if ( mismatch ) begin
	                    $fdisplay( fd );
	                end

	                $fwrite( fd, "%08x ", rvfi_pc_rdata );
	                $fwrite( fd, "%08x ", rvfi_insn );
	                $fwrite( fd, "%s ", mnemonic );


					if ( expect_rd_addr_valid ) begin
	                	$fwrite( fd, "%s <= " , register_names[ expect_rd_addr*3*8  +: 3*8 ] );
						$fwrite( fd, "%x ", expect_rd_wdata );
	                end else begin
						$fwrite( fd, "     " );
					end

					if ( expect_rs1_addr_valid ) begin
						$fwrite( fd, "%s " , register_names[ expect_rs1_addr*3*8 +: 3*8 ] );
						if ( expect_rs1_addr != 0 ) $fwrite( fd, "(%x) ", shadow_rs1_rdata );
					end else begin
						$fwrite( fd, "     " );
					end

					if ( expect_rs2_addr_valid ) begin
						$fwrite( fd, "%s " , register_names[ expect_rs2_addr*3*8 +: 3*8 ] );
						if ( expect_rs2_addr != 0 )$fwrite( fd, "(%x) ", shadow_rs2_rdata );
					end else begin
						$fwrite( fd, "     " );
					end

					if ( has_immediate ) $fwrite( fd, "%x ", immediate );

					if ( is_store ) $fwrite( fd, "write mem[%x] = %x ", rvfi_mem_addr, rvfi_mem_wdata );
					if ( is_load  ) $fwrite( fd, "read  mem[%x] = %x ", rvfi_mem_addr, rvfi_mem_rdata );



					$fdisplay( fd );

					$fdisplay( fd, "pc_next:  %x : %x", rvfi_pc_wdata, expect_pc_next );
					if ( expect_rd_request ) begin
	                	$fdisplay( fd, "rd_addr: %x : %x" , rvfi_rd_addr, expect_rd_addr );
						$fdisplay( fd, "rd_data: %x : %x" , rvfi_rd_wdata, expect_rd_wdata );
					end
					if ( expect_rs1_request ) begin
	                	$fdisplay( fd, "rs1_addr: %x : %x" , rvfi_rs1_addr, expect_rs1_addr );
						$fdisplay( fd, "rs1_data: %x : %x" , rvfi_rs1_rdata, shadow_rs1_rdata );
					end
					if ( expect_rs2_request ) begin
	                	$fdisplay( fd, "rs2_addr: %x : %x" , rvfi_rs2_addr, expect_rs2_addr );
						$fdisplay( fd, "rs2_data: %x : %x" , rvfi_rs2_rdata, shadow_rs2_rdata );
					end
					if ( is_store || is_load ) begin


						$fdisplay( fd, "mem_addr: %x : %x" , rvfi_mem_addr, expect_mem_addr );
					end




	                if ( mismatch ) begin
	                    $fwrite( fd, "%08x ", rvfi_pc_rdata );
	                    $fwrite( fd, "%08x ", rvfi_insn );
	                    $fwrite( fd, "%s ", mnemonic );
	                    $fwrite( fd, "%s " , register_names[ expect_rd_addr*3*8 +: 3*8 ] );
	                    $fwrite( fd, "%s " , register_names[ expect_rs1_addr*3*8 +: 3*8 ] );
	                    $fwrite( fd, "%s " , register_names[ expect_rs2_addr*3*8 +: 3*8 ] );

	                    $fdisplay( fd );
	                end






            	end else begin
                	$fwrite( fd, "illegal instruction" );
            	end

            	$fdisplay( fd );
			end
        end
    end

endmodule
module rvfi_monitor (


    input          clk,
    input          reset,

	input          rvfi_valid,
	input   [63:0] rvfi_order,
	input   [31:0] rvfi_insn,
	input          rvfi_trap,
	input          rvfi_halt,
	input          rvfi_intr,
	input   [ 1:0] rvfi_mode,
	input   [ 1:0] rvfi_ixl,
	input   [ 4:0] rvfi_rs1_addr,
	input   [ 4:0] rvfi_rs2_addr,
	input   [31:0] rvfi_rs1_rdata,
	input   [31:0] rvfi_rs2_rdata,
	input   [ 4:0] rvfi_rd_addr,
	input   [31:0] rvfi_rd_wdata,
	input   [31:0] rvfi_pc_rdata,
	input   [31:0] rvfi_pc_wdata,

	input   [31:0] rvfi_mem_addr,
	input   [ 3:0] rvfi_mem_rmask,
	input   [ 3:0] rvfi_mem_wmask,
	input   [31:0] rvfi_mem_rdata,
	input   [31:0] rvfi_mem_wdata,

	input   [63:0] rvfi_csr_mcycle_rmask,
	input   [63:0] rvfi_csr_mcycle_wmask,
	input   [63:0] rvfi_csr_mcycle_rdata,
	input   [63:0] rvfi_csr_mcycle_wdata,

	input   [63:0] rvfi_csr_minstret_rmask,
	input   [63:0] rvfi_csr_minstret_wmask,
	input   [63:0] rvfi_csr_minstret_rdata,
	input   [63:0] rvfi_csr_minstret_wdata

);







wire             expect_rvfi_valid        ;
wire      [63:0] expect_rvfi_order        ;
wire      [31:0] expect_rvfi_insn         ;
wire             expect_rvfi_trap         ;
wire             expect_rvfi_halt         ;
wire             expect_rvfi_intr         ;
wire      [ 1:0] expect_rvfi_mode         ;
wire      [ 1:0] expect_rvfi_ixl          ;
wire      [ 4:0] expect_rvfi_rs1_addr     ;
wire      [ 4:0] expect_rvfi_rs2_addr     ;
wire      [31:0] expect_rvfi_rs1_rdata    ;
wire      [31:0] expect_rvfi_rs2_rdata    ;
wire      [ 4:0] expect_rvfi_rd_addr      ;
wire      [31:0] expect_rvfi_rd_wdata     ;
wire      [31:0] expect_rvfi_pc_rdata     ;
wire      [31:0] expect_rvfi_pc_wdata     ;
wire      [31:0] expect_rvfi_mem_addr     ;
wire      [ 3:0] expect_rvfi_mem_rmask    ;
wire      [ 3:0] expect_rvfi_mem_wmask    ; 
wire      [31:0] expect_rvfi_mem_rdata    ;
wire      [31:0] expect_rvfi_mem_wdata    ;
wire      [63:0] expect_rvfi_csr_mcycle_rmask      ;
wire      [63:0] expect_rvfi_csr_mcycle_wmask      ;
wire      [63:0] expect_rvfi_csr_mcycle_rdata      ;
wire      [63:0] expect_rvfi_csr_mcycle_wdata      ;
wire      [63:0] expect_rvfi_csr_minstret_rmask    ;
wire      [63:0] expect_rvfi_csr_minstret_wmask    ;
wire      [63:0] expect_rvfi_csr_minstret_rdata    ;
wire      [63:0] expect_rvfi_csr_minstret_wdata    ;

wire      [31:0] expect_pc_next                  ;
wire      [31:0] expect_insn_addr                ;
wire      [ 4:0] expect_rs1_addr                 ;
wire      [ 4:0] expect_rs2_addr                 ;
wire      [ 4:0] expect_rd_addr                 ;

wire             expect_rs1_request             ;
wire             expect_rs2_request             ;
wire             expect_rd_request              ;



wire      [31:0] shadow_rs1_rdata               ;
wire      [31:0] shadow_rs2_rdata               ;
wire      [31:0] expect_rd_wdata                ;

wire             expect_mem_valid               ;
wire             expect_mem_instr               ;
wire      [31:0] expect_mem_addr                ;
wire      [31:0] expect_mem_wdata               ;
wire      [ 3:0] expect_mem_wstrb               ;
wire      [ 3:0] expect_mem_rmask               ;

wire      [63:0] expect_csr_time                ;
wire      [63:0] expect_csr_cycle               ;
wire      [63:0] expect_csr_instret             ;



integer   fd;
initial begin
    fd = $fopen( "rvfi_mon.txt", "w" );
end

wire  insn_valid = 1 ;




reg [63:0]  csr_cycle;
reg [63:0]  csr_time;
reg [63:0]  csr_instret;

always @(posedge clk) begin
	if ( reset ) begin
		csr_cycle   <= 0 ;
		csr_time    <= 0 ; 
		csr_instret <= 0 ;
	end else begin
		csr_cycle   <= csr_cycle   + 1 ;
		csr_time    <= csr_time    + 1 ; 
		if (rvfi_valid) begin
            csr_instret <= csr_instret + 1 ;
        end
	end
end

integer instruction_cycles;
integer instruction_cycles_next;
always @(*) begin
	instruction_cycles_next = reset ? 0 : rvfi_valid ? 1 : (instruction_cycles+1) ; 
end
always @(posedge clk) begin
	instruction_cycles <= instruction_cycles_next;
end

localparam PROGADDR_RESET = 'h10000;
localparam STACKADDR      = 'h10000;



reg [31:0] pc;








initial pc = PROGADDR_RESET;
always @(posedge clk) begin
	pc <= reset ? PROGADDR_RESET : ( expect_insn_complete ? expect_pc_next : pc ) ;
end

integer i;
reg [31:0] registers [ 0:31 ];
always @(posedge clk) begin
	if ( reset ) begin
		registers[ 0] <= 0;
        registers[ 1] <= 32'hx;
		registers[ 2] <= STACKADDR;
        for( i=3; i <32; i=i+1 ) begin
            registers[i] <= 32'hx;
        end
	end
	if ( expect_rd_request ) begin
		registers[ expect_rd_addr ] <= expect_rd_wdata;
	end
end

assign shadow_rs1_rdata = expect_rs1_request ? registers[ expect_rs1_addr ] : 32'bx;
assign shadow_rs2_rdata = expect_rs2_request ? registers[ expect_rs2_addr ] : 32'bx;


wire [3:0] mem_wstrb;







comb_rv32 comb_rv32 (

	  .trap            ( expect_trap           )
	, .pc              ( rvfi_pc_rdata         )
	, .pc_next         ( expect_pc_next        )
	, .pc_next_valid   ( expect_pc_next_valid  )
	, .insn_addr       ( expect_insn_addr      )
	, .insn            ( rvfi_insn             )
	, .insn_valid      ( rvfi_valid            )
	, .insn_complete   ( expect_insn_complete  )
	, .rs1_addr        ( expect_rs1_addr       )
	, .rs2_addr        ( expect_rs2_addr       )
	, .rd_addr         ( expect_rd_addr        )
	, .rs1_addr_valid  ( expect_rs1_addr_valid )
	, .rs2_addr_valid  ( expect_rs2_addr_valid )
	, .rd_addr_valid   ( expect_rd_addr_valid  )

	, .rs1_request     ( expect_rs1_request           )
	, .rs2_request     ( expect_rs2_request           )
	, .rd_request      ( expect_rd_request            )

	, .rs1_rdata       ( shadow_rs1_rdata      )
	, .rs2_rdata       ( shadow_rs2_rdata      )
	, .rd_wdata        ( expect_rd_wdata       )
	, .rs1_ready       (             1'b1      )
	, .rs2_ready       (             1'b1      )
	, .rd_ready        (             1'b1      )
	, .mem_valid       ( expect_mem_valid      )
	, .mem_instr       ( expect_mem_instr      )
	, .mem_ready       (             1'b1      )
	, .mem_addr        ( expect_mem_addr       )
	, .mem_wdata       ( expect_mem_wdata      )
	, .mem_wstrb       ( expect_mem_wstrb      )
	, .mem_rmask       ( expect_mem_rmask      )
	, .mem_rdata       (   rvfi_mem_rdata      )
	, .csr_time        (        csr_time       )
	, .csr_cycle       (        csr_cycle      )
	, .csr_instret     (        csr_instret    )



	, .rvfi_valid              ( expect_rvfi_valid                  )
	, .rvfi_order              ( expect_rvfi_order                  )
	, .rvfi_insn               ( expect_rvfi_insn                   )
	, .rvfi_trap               ( expect_rvfi_trap                   )
	, .rvfi_halt               ( expect_rvfi_halt                   )
	, .rvfi_intr               ( expect_rvfi_intr                   )
	, .rvfi_mode               ( expect_rvfi_mode                   )
	, .rvfi_ixl                ( expect_rvfi_ixl                    )
	, .rvfi_rs1_addr           ( expect_rvfi_rs1_addr               )
	, .rvfi_rs2_addr           ( expect_rvfi_rs2_addr               )
	, .rvfi_rs1_rdata          ( expect_rvfi_rs1_rdata              )
	, .rvfi_rs2_rdata          ( expect_rvfi_rs2_rdata              )
	, .rvfi_rd_addr            ( expect_rvfi_rd_addr                )
	, .rvfi_rd_wdata           ( expect_rvfi_rd_wdata               )
	, .rvfi_pc_rdata           ( expect_rvfi_pc_rdata               )
	, .rvfi_pc_wdata           ( expect_rvfi_pc_wdata               )
	, .rvfi_mem_addr           ( expect_rvfi_mem_addr               )
	, .rvfi_mem_rmask          ( expect_rvfi_mem_rmask              )
	, .rvfi_mem_wmask          ( expect_rvfi_mem_wmask              )
	, .rvfi_mem_rdata          ( expect_rvfi_mem_rdata              )
	, .rvfi_mem_wdata          ( expect_rvfi_mem_wdata              )
	, .rvfi_csr_mcycle_rmask   ( expect_rvfi_csr_mcycle_rmask       )
	, .rvfi_csr_mcycle_wmask   ( expect_rvfi_csr_mcycle_wmask       )
	, .rvfi_csr_mcycle_rdata   ( expect_rvfi_csr_mcycle_rdata       )
	, .rvfi_csr_mcycle_wdata   ( expect_rvfi_csr_mcycle_wdata       )
	, .rvfi_csr_minstret_rmask ( expect_rvfi_csr_minstret_rmask     )
	, .rvfi_csr_minstret_wmask ( expect_rvfi_csr_minstret_wmask     )
	, .rvfi_csr_minstret_rdata ( expect_rvfi_csr_minstret_rdata     )
	, .rvfi_csr_minstret_wdata ( expect_rvfi_csr_minstret_wdata     )

);


reg  [5*8-1:0] mnemonic = "???";









	assign insn_addr = { pc[31:1], 1'b0 };



	reg insn_decode_valid;



	wire [31:0] insn = rvfi_insn;

	wire [6:0] insn_field_opcode = insn[6:0];
	wire [2:0] insn_field_funct3 = insn[14:12];
	wire [6:0] insn_field_funct7 = insn[31:25];
	wire [4:0] insn_field_rd     = insn[11:7];
	wire [4:0] insn_field_rs1    = insn[19:15];
	wire [4:0] insn_field_rs2    = insn[24:20];












	reg is_alu_immediate;

	wire [31:0] immediate_12bit = { {20{insn[31]}}, insn[31:20] };
	wire [31:0] immediate_12bit_for_stores = { immediate_12bit[31:5], insn[11:7] };
	wire [31:0] immediate_for_jal = { {12{insn[31]}}, insn[19:12], insn[20], insn[30:21], 1'b0 };
	wire [31:0] immediate_for_branches = { {20{insn[31]}}, insn[7], insn[ 30:25], insn[11:8], 1'b0 };

	wire [31:0] pc_next_no_branch = insn_addr + 4;
	wire [31:0] pc_next_branch = ( insn_addr + immediate_for_branches ) & 32'hFFFF_FFFE;


wire [8*4*8:0] branch_mnemonics = "BGEUBLTUBGE BLT         BNE BEQ ";







integer immediate;
reg     has_immediate;

reg     is_load;
reg     is_store;

	always @* begin









		is_alu_immediate = 0;
		mnemonic = "???";
		immediate = 0;
		has_immediate = 0;
		is_load = 0;
		is_store = 0;












		if ( insn_valid ) begin 

			if (insn_field_opcode == 7'b 01_101_11) begin
				insn_decode_valid = 1;
				mnemonic = "LUI";


				has_immediate = 1;
				immediate = insn[31:12];
			end
			if (insn_field_opcode == 7'b 00_101_11) begin
				insn_decode_valid = 1;
				mnemonic = "AUIPC";


				has_immediate = 1;
				immediate = insn[31:12];

			end
			if (insn_field_opcode == 7'b 11_011_11) begin
				insn_decode_valid = 1;
				mnemonic = "JAL";





				has_immediate = 1;
				immediate = immediate_for_jal;

			end
			if (insn_field_opcode == 7'b 11_001_11) begin
				if (  insn_field_funct3 == 3'b 000 ) begin
					insn_decode_valid = 1;
					mnemonic = "JALR";





					has_immediate = 1;
					immediate = immediate_12bit;

				end
			end

			if (insn_field_opcode == 7'b 11_000_11) begin
				insn_decode_valid = (insn_field_funct3 != 3'b 010) && (insn_field_funct3 != 3'b 011);



				if ( insn_decode_valid ) begin
					mnemonic = branch_mnemonics[ 4*8*insn_field_funct3 +: 4*8];
					has_immediate = 1;
					immediate = immediate_for_branches;









					end


			end

			if (insn_field_opcode == 7'b 00_000_11) begin
				insn_decode_valid = (insn_field_funct3 != 3'b 011) && (insn_field_funct3 != 3'b 110) && (insn_field_funct3 != 3'b 111);




					has_immediate = 1;
					immediate = immediate_12bit;
					is_load = 1;

				if (insn_field_funct3 == 3'b000 ) begin


					mnemonic = "LB";
				end
				if (insn_field_funct3 == 3'b100 ) begin


					mnemonic = "LBU";
				end
				if (insn_field_funct3 == 3'b001 ) begin


					mnemonic = "LH";
				end
				if (insn_field_funct3 == 3'b101 ) begin


					mnemonic = "LHU";
				end
				if (insn_field_funct3 == 3'b010 ) begin


					mnemonic = "LW";
				end
			end

			if (insn_field_opcode == 7'b 01_000_11) begin
				insn_decode_valid = (insn_field_funct3 == 3'b 000) || (insn_field_funct3 == 3'b 001) || (insn_field_funct3 == 3'b 010);






					has_immediate = 1;
					immediate = immediate_12bit_for_stores;
					is_store = 1;


				if (insn_field_funct3 == 3'b000 ) begin

					mnemonic = "SB";
				end
				if (insn_field_funct3 == 3'b001 ) begin

					mnemonic = "SH";
				end
				if (insn_field_funct3 == 3'b010 ) begin

					mnemonic = "SW";
				end

			end

			if ( (insn_field_opcode == 7'b 01_100_11) || (insn_field_opcode == 7'b 00_100_11) ) begin
				is_alu_immediate = (insn_field_opcode == 7'b 00_100_11);
				if ( is_alu_immediate ) begin

					has_immediate = 1;
					immediate = immediate_12bit;					
				end

				case (insn_field_funct3)
					3'b 000: begin




						if (is_alu_immediate || insn_field_funct7 == 7'b 0000000) begin
							insn_decode_valid = 1;

							mnemonic = has_immediate ? "ADDI" : "ADD";
						end else if ( insn_field_funct7 == 7'b 0100000 ) begin
							insn_decode_valid = 1;

							mnemonic = has_immediate ? "SUBI" : "SUB";						end
					end
					3'b 101: begin





						if ( insn_field_funct7 == 7'b 0000000 ) begin
							insn_decode_valid = 1;

							mnemonic = has_immediate ? "SRLI" : "SRL";
						end else if ( (!is_alu_immediate && insn_field_funct7 == 7'b 0100000 ) || ( is_alu_immediate && insn_field_funct7 == 7'b 0100000 ) ) begin
							insn_decode_valid = 1;
							mnemonic = has_immediate ? "SRAI" : "SRA";

						end
					end
					3'b001: begin 

						if ( insn_field_funct7 == 7'b 0000000 ) begin 
							insn_decode_valid = 1;




							mnemonic = is_alu_immediate ? "SLLI" : "SLL";

						end
					end
					default: begin
						if ( is_alu_immediate || insn_field_funct7 == 7'b 0000000 ) begin
							insn_decode_valid = 1;



							case (insn_field_funct3)



								3'b010: begin

									mnemonic = is_alu_immediate ? "SLTI" : "SLT";
								end
								3'b011: begin

									mnemonic = is_alu_immediate ? "SLTUI" : "SLTU";
								end
								3'b100: begin

									mnemonic = is_alu_immediate ? "XORI" : "XOR";
								end
								3'b110: begin

									mnemonic = is_alu_immediate ? "ORI" : "OR";
								end
								3'b111: begin

									mnemonic = is_alu_immediate ? "ANDI" : "AND";
								end
							endcase
						end
					end
				endcase
			end
			if (insn_field_opcode == 7'b 11_100_11) begin 
				if ( insn_field_rs1 == 0 && insn_field_funct3 == 3'b010 ) begin
					case (insn[31:20])
						12'hC00: begin
							insn_decode_valid = 1 ;


						end
						12'hC01: begin
							insn_decode_valid = 1 ;


						end
						12'hC02: begin
							insn_decode_valid = 1 ;


						end
						12'hC80: begin
							insn_decode_valid = 1 ;


						end
						12'hC81: begin
							insn_decode_valid = 1 ;


						end
						12'hC82: begin
							insn_decode_valid = 1 ;


						end
					endcase
					end
			end
		end
	end



wire mismatch = 0;





	reg [32*3*8:0] register_names  = {
		  " t6 t5 t4 t3s11s10 s9 s8"
		, " s7 s6 s5 s4 s3 s2 a7 a6"
		, " a5 a4 a3 a2 a1 a0 s1 fp"
		, " t2 t1 t0 tp gp sp ra 00"
	};







    always @(posedge clk) begin
        #1;



        if (reset ) begin
            $fdisplay( fd, "reset" );
        end else begin
            if (rvfi_valid) begin
				if ( insn_decode_valid ) begin 

	                if ( mismatch ) begin
	                    $fdisplay( fd );
	                end

	                $fwrite( fd, "%08x ", rvfi_pc_rdata );
	                $fwrite( fd, "%08x ", rvfi_insn );
	                $fwrite( fd, "%s ", mnemonic );


					if ( expect_rd_addr_valid ) begin
	                	$fwrite( fd, "%s <= " , register_names[ expect_rd_addr*3*8  +: 3*8 ] );
						$fwrite( fd, "%x ", expect_rd_wdata );
	                end else begin
						$fwrite( fd, "     " );
					end

					if ( expect_rs1_addr_valid ) begin
						$fwrite( fd, "%s " , register_names[ expect_rs1_addr*3*8 +: 3*8 ] );
						if ( expect_rs1_addr != 0 ) $fwrite( fd, "(%x) ", shadow_rs1_rdata );
					end else begin
						$fwrite( fd, "     " );
					end

					if ( expect_rs2_addr_valid ) begin
						$fwrite( fd, "%s " , register_names[ expect_rs2_addr*3*8 +: 3*8 ] );
						if ( expect_rs2_addr != 0 )$fwrite( fd, "(%x) ", shadow_rs2_rdata );
					end else begin
						$fwrite( fd, "     " );
					end

					if ( has_immediate ) $fwrite( fd, "%x ", immediate );

					if ( is_store ) $fwrite( fd, "write mem[%x] = %x ", rvfi_mem_addr, rvfi_mem_wdata );
					if ( is_load  ) $fwrite( fd, "read  mem[%x] = %x ", rvfi_mem_addr, rvfi_mem_rdata );



					$fdisplay( fd );

					$fdisplay( fd, "pc_next:  %x : %x", rvfi_pc_wdata, expect_pc_next );
					if ( expect_rd_request ) begin
	                	$fdisplay( fd, "rd_addr: %x : %x" , rvfi_rd_addr, expect_rd_addr );
						$fdisplay( fd, "rd_data: %x : %x" , rvfi_rd_wdata, expect_rd_wdata );
					end
					if ( expect_rs1_request ) begin
	                	$fdisplay( fd, "rs1_addr: %x : %x" , rvfi_rs1_addr, expect_rs1_addr );
						$fdisplay( fd, "rs1_data: %x : %x" , rvfi_rs1_rdata, shadow_rs1_rdata );
					end
					if ( expect_rs2_request ) begin
	                	$fdisplay( fd, "rs2_addr: %x : %x" , rvfi_rs2_addr, expect_rs2_addr );
						$fdisplay( fd, "rs2_data: %x : %x" , rvfi_rs2_rdata, shadow_rs2_rdata );
					end
					if ( is_store || is_load ) begin


						$fdisplay( fd, "mem_addr: %x : %x" , rvfi_mem_addr, expect_mem_addr );
					end




	                if ( mismatch ) begin
	                    $fwrite( fd, "%08x ", rvfi_pc_rdata );
	                    $fwrite( fd, "%08x ", rvfi_insn );
	                    $fwrite( fd, "%s ", mnemonic );
	                    $fwrite( fd, "%s " , register_names[ expect_rd_addr*3*8 +: 3*8 ] );
	                    $fwrite( fd, "%s " , register_names[ expect_rs1_addr*3*8 +: 3*8 ] );
	                    $fwrite( fd, "%s " , register_names[ expect_rs2_addr*3*8 +: 3*8 ] );

	                    $fdisplay( fd );
	                end






            	end else begin
                	$fwrite( fd, "illegal instruction" );
            	end

            	$fdisplay( fd );
			end
        end
    end

endmodule