This paper is report on Verilog analysis methods and creates a living example on a Verilog project consisting of files that need to be verified and following the pipeline run in a cycle of 4000 times
The paper is written in standard IEEE form and is addressed to those with an elementary to medium knowledge of Verilog who are interested following the run procedure and code writing of a project demonstrating Verilog abilities in the required 4000 running cycle. The project made in order to demonstrate how a state machine behaves with fetch, decode and writeback using Verilog. The software used was System Verilog which is a combination of C/C++, Verilog and also Co-Design Automation Superlog language and was run in a home PC. On this manner the level of abstraction was high regardless of the low-cost home PC.
Contents
1. INTRODUCTION.
2. VERILOG AND DESIGN FLOW
3. SYSTEM LEVEL VERIFICATION
4. RTL DESIGN AND CREATION OF TEST BENCH
5. LOOK AHEAD SYNTHESIS.
6. ABSTRUCTION LEVELS
7. DESIGN PROCESS
8. SYSTEM LEVEL
9. ANALOG
10. DIGITAL.
11. VALUES WIRES AND REGISTERS..
12. VECTORS
13. DIRECTIVES AND LITERALS
14. COMBINING VECTORS
15. OPERATORS
16. RUNNING CYCLE.
17. Conclusions
18. References
19. Appendix
Abstract — this paper is report on Verilog analysis methods and creates a living example on a Verilog project consisting of files that need to be verified and following the pipeline run in a cycle of 4000 times
The paper is written in standard IEEE form and is addressed to those with an elementary to medium knowledge of Verilog who are interested following the run procedure and code writing of a project demonstrating Verilog abilities in the required 4000 running cycle. The project made in order to demonstrate how a state machine behaves with fetch, decode and writeback using Verilog. The software used was System Verilog which is a combination of C/C++, Verilog and also Co-Design Automation Superlog language and was run in a home PC. On this manner the level of abstraction was high regardless of the low-cost home PC.
1. INTRODUCTION
Verilog is a HDL language( Hardware Description Language) intended for describing systems electronic circuits and electronic designs.
What Verilog does is verification with simulation for logic synthesis, test analysis (with fault grading and testability analysis) and finally timing analysis and parallel activity flow.
Examples of designed circuits using Verilog hardware description language are the Intel Pentium microprocessor, the AMD K5, the AMD K6, the Athlon ARM7 etc. and thousands more are using Verilog HDL.
Verilog is used to produce the model of a system. This is done mainly for reasons of requirement specification, documentation, and control through simulation, formal verification and final synthesis of the required circuit.
The aim is to synthesize a circuit as much reliable as possible with low demands on cost, with low timing constraints and avoid in advance designing faults.
2. Verilog and Design flow
The design flow is in ASIC (Standard cell, gate array given in the next diagram summarizes the design in high level.
What must be noticed is that each section can be fragmented in to smaller sections and as errors are revealed these sections in the flow will be iterated.
When Verilog modeling is applied, these parts are:
a. Structural to connect the modules e.g. Counter counter_1 (clk, enable, count_out)
b. Data Flow when we are using basic gates e.g. wire = (a&b)/ (c&d) ;
c. Behavioral or Procedural with procedural calls e.g. always @ (posedge clk) begin…end
d. Synthesizable versus not synthesizable e.g.
a < = # 10b+1.
e. RTL register transfer level when the design is been made in register level.
illustration not visible in this excerpt
Figure 1: Design flow [1]
3. System Level Verification
The basic use of Verilog is to simulate and model of a system that contains FPGAs and ASICs.
This allows the system to be fully analyzed creating a functional description.
This will also allow the system to be validated before starting a working design in detail. It also allows the designer to have a partial description of the system in specific properties and with a performance model to investigate potential performance bottlenecks.
4. RTL design and creation of test bench
To start the detail design, of FPGAs or ASICs the partitioning and system architecture of the entire system must be stable.
This is done by capturing some test cases in Verilog and completing the Verilog design at the level of register transfer.
Both of these are adulatory and, in some cases, different designers or full teams consisting of many people are used in order not to mix the specifications and to reach conclusions without prior knowledge of the other team work.
5. LOOK AHEAD SYNTHESIS
The basic synthesis production is delayed until a complete functional simulation is achieved.
What bust be noticed is that in order to facilitate the evaluation of the architecture design and to assure area data and correct speed some early synthesis is required.
6. ABSTRUCTION LEVELS
For different stages in the designing process Verilog can span many levels of abstraction as in the next figure.
In this way, Verilog, at the highest level, can have random probability distributions and queues. Thus, Verilog can model the system at an elevated level of abstraction to prove how functional the system is, especially at the partitioning stage and the full analysis of the system.
In the end what Verilog does is to provide register transfer level analysis, very useful in designing digital circuits.
illustration not visible in this excerpt
Figure 2: Abstraction Levels 1[1]
It also provided synthesis at the switching level logic simulation and synthesis at the gate level. This included fault grading, dynamic timing analysis and testability analysis. In addition, Verilog can be used to take checkpoints and trace waveforms for a better evaluation and measurements of the system.
7. DESIGN PROCESS
Verilog contributions in designing can be seen in Figure 3.
This included the full package from system analysis and partitioning to mixed signal simulation and final layout of the design.
illustration not visible in this excerpt
Figure 3: Design Process [1]
8. SYSTEM LEVEL
The drawback in Verilog is that it forbids the designer to deal with predefined system functions and overloaded operators while VHDL can.
It also has the limitation of the built-in language futures that will allow, up to certain degree, modeling performance, queueing and throughput.
illustration not visible in this excerpt
Figure 4: Verilog system analysis
9. ANALOG
Since Verilog is a programming, language can also be used for analog simulation.
Verilog especially all cases in mixed signal and normal analog signal simulation.
10. DIGITAL
Verilog is best used in today’s high-level digital hardware design within a full integrated environment in designing.
Thus, Verilog is used in switch level simulation, fault simulations and provide worst-case scenarios in timing throughout the simulation procedure. It can also simulate routing delays and gate level fan out loading problems.
The level of abstraction of RTL can be useful for proper simulation before synthesis of the entire system project.
11. VALUES WIRES AND REGISTERS
The basic structural piece is the bit with values 0 and 1. In X we don’t know the value or we don’t care and Z is not driven. The values are transmitted through wires- nets and are kept in registers. In the registers, they are combined and logical expressions are created. The expressions can be assigned in to the registers or wires.
Wires represent different unit connections. There are various types of wires but the most common one has the title “wire”.
Wires do not hold values, they just transfer them and value assignments to wires are done only once. In the following example, any change in x and y are immediately shown in z.
illustration not visible in this excerpt
The register “reg” holds the value assigned to him until the next assignment (like a variable in a programming language). It is used to describe the storage elements as flip-flops, latches memory etc. It is used for combined logic because it is more convenient than the net type.
12. VECTORS
One bit cannot do much. We usually need a group of bits where everyone’s place is important (e.g. representing a number). They are called vectors and they exist in both reg and wire. Describing the vector, it can be upper: lower with upper >= lower. The lower can be any number not necessarily zero. Verilog assigns zeros on the left whatever bits are missing at the assignment. Newer versions of Verilog add predefined types of reg and wire.
illustration not visible in this excerpt
13. DIRECTIVES AND LITERALS
Verilog assign steady values, macros and combines the files. It also translates conditionally in to a certain time frame.
illustration not visible in this excerpt
Literals usually have a predefined size and they usually start with “size ‘base”.
-size in bits, b-binary, o-octal, h-hexadecimal, d-decimal.
X or Y sets 1 bit for ‘b, 3 bit for ‘o, 4 bit for “h.
If the most significant bit is 0, x or z, it extends automatically till the left edge.
illustration not visible in this excerpt
14. COMBINING VECTORS
To combine vectors, we use {vector1, vector2, …, vectorn}. We can also combine the same vector by using { n { vector } }. It can also be used in the left side of an assignment.
illustration not visible in this excerpt
15. OPERATORS
In Verilog the following operators are used
illustration not visible in this excerpt
16. RUNNING CYCLE
Verilog was used to describe and make the event driven systems (change in state) with simulation starting at t=0. Events, as they processed created new events. When all events, at time t were actually processed the time advanced to time t+1 (cycles) and stopped at the required cycle time. The aim of the project was to run the program for 4000 cycles. The program stopped at the required cycle time of 4000 and they were no more events in the queue.
The Verilog language used was System Verilog which is a combination of C/C++, Verilog and also Co-Design Automation Superlog language. On this manner the level of abstraction was high.
In the required project I was given a tar file called lab5. In this file I had a list of directories. In one of these directories, I had a directory called RTL. In this RTL directory, I had a couple of files which were processed and the whole project consisted of four parts
Fetch
Decode
Execute
Writeback.
What it actually does is the basic operational process of a computer system. The running cycle is the process to describe how a computer retrieves a program instruction from its memory. The computer then determines what this instruction describes and how this is to be done, and then fulfils these actions. This running cycle is constantly repeated by the CPU ( (computer's central processing unit, from the initial start of the computer (boot-up) until the computer shuts down. [2]
illustration not visible in this excerpt
Figure 5: Running Cycle [2]
The basic pipeline was completed as follows:
illustration not visible in this excerpt
Figure 5 [2] Reduced Instruction Set Computing
The Basic five-stage pipeline in a Reduced Instruction Set Computing (RISC) machine (WB = Register write back, EX = Execute, ID = Instruction Decode, IF = Instruction Fetch, MEM = Memory access,). In figure 5 the time is represented in the horizontal axis and the successive instructions in the vertical. AS we can see in the green column, the last instruction is doing the instruction fetch and the initial instruction is in WB stage. [2].
The project was completed in the required 4000 cycles timing and a part of the version of the output files are given as follows in Appendix.
17. CONCLUSION
Verilog hardware Description Language (HDL) is a very important language in today’s world used in technology world and various companies designing Field Programming Gate arrays (FPFAs) and Application Specific Integrated Circuits (ASICs). The knowledge of this language is very important to engineers who are in Digital technology and networking systems to
The project was made in order to demonstrate how a state machine behaves with fetch, decode and writeback using Verilog. The software used was System Verilog which is a combination of C/C++, Verilog and also Co-Design Automation Superlog language. On this manner the level of abstraction was high.
The project had to essentially finish these four parts of Verilog:
Fetch
Decode
Execute
Writeback
and to run the project for 4000 cycles proving the concept of pipelining in a reduced instruction set computing (RISC).
REFERENCES
1. https://courses.cs.washington.edu/courses/cse567/01au/
2. https://en.wikipedia.org/wiki/Instruction_cycle
3. http://teachers.teicm.gr/kalomiros/Mtptx/e-books/Essential_VHDL_Kalomiros.pdf
4. http://docplayer.gr/33649362-Iy225-organosi-ypologiston-eisagogi-sti-verilog.html
5. https://ipfs.io/ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki/RISC.html
6. https://ipfs.io/ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki/MIPS_architecture.html
Appendix
`include "rv64.vh"
module pyrm_execute_block
(input clk,
input reset_pyri,
input [64-1:0] pc_pyri,
input pc_valid_pyri,
output logic pc_retry_pyro,
input [64-1:0] in1_pyri,
input in1_valid_pyri,
output logic in1_retry_pyro,
input [64-1:0] in2_pyri,
input in2_valid_pyri,
output logic in2_retry_pyro,
input [32-1:0] inst_pyri,
input inst_valid_pyri,
output logic inst_retry_pyro,
output logic [64-1:0] pc_pyro,
output logic pc_valid_pyro,
input pc_retry_pyri,
output logic [32-1:0] inst_pyro,
output logic inst_valid_pyro,
input inst_retry_pyri,
output logic [64-1:0] rdata_pyro,
output logic rdata_valid_pyro, //replace with inst_o
input rdata_retry_pyri,
output logic [64-1:0] raddr_pyro,
output logic raddr_valid_pyro,
input raddr_retry_pyri,
output logic [64-1:0] branch_pc_pyro,
output logic branch_pc_valid_pyro,
input branch_pc_retry_pyri
);
wire all_valid;
wire all_retry;
assign all_valid = in1_valid_pyri | in2_valid_pyri | pc_valid_pyri | inst_valid_pyri;
assign all_retry = pc_retry_pyri | inst_retry_pyri | rdata_retry_pyri | raddr_retry_pyri | branch_pc_retry_pyri;
//assign pc_retry_pyro = pc_valid_pyri & ~all_valid;
//assign inst_retry_pyro = inst_valid_pyri & ~all_valid;
//assign in1_retry_pyro = in1_valid_pyri & ~all_valid;
//assign in2_retry_pyro = in2_valid_pyri & ~all_valid;
assign pc_retry_pyro = all_retry;
assign inst_retry_pyro = all_retry;
assign in1_retry_pyro = all_retry;
assign in2_retry_pyro = all_retry;
reg [32-1:0] temp;
reg [64-1:0] temp2;
wire [7-1:0] op;
wire [7-1:0] funct7;
wire [3-1:0] funct3;
wire [12:1] B_immediate;
wire [11:0] I_immediate;
assign op = inst_pyri[6:0];
assign funct3 = inst_pyri[14:12];
assign funct7 = inst_pyri[31:25];
assign B_immediate = {inst_pyri[31],inst_pyri[7],inst_pyri[30:25],inst_pyri[11:8]};
assign I_immediate = inst_pyri[31:20];
always @(*) begin
pc_pyro = 64'd0;
pc_valid_pyro = 1'b0;
inst_pyro = 32'd0;
inst_valid_pyro = 1'b0;
rdata_pyro = 64'd0;
rdata_valid_pyro = 1'b0;
raddr_pyro = 64'd0;
raddr_valid_pyro = 1'b0;
branch_pc_pyro = 64'd0;
branch_pc_valid_pyro = 1'b0;
if (all_valid) begin
pc_pyro = pc_pyri;
pc_valid_pyro = pc_valid_pyri;
inst_pyro = inst_pyri;
inst_valid_pyro = inst_valid_pyri;
if (op == `OP_ARITH && funct3 == `FUNCT3_ARTIH_ADD && funct7 == `FUNCT7_ARTIH_ADD) begin
//ADD
rdata_pyro = $signed(in1_pyri) + $signed(in2_pyri);
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_ARITH && funct3 == `FUNCT3_ARTIH_SUB && funct7 == `FUNCT7_ARTIH_SUB) begin
//SUB
rdata_pyro = $signed(in1_pyri) - $signed(in2_pyri);
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_ARITH && funct3 == `FUNCT3_ARTIH_SLL && funct7 == `FUNCT7_ARTIH_ADD) begin
//SLL
rdata_pyro = in1_pyri << in2_pyri[4:0];
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_ARITH && funct3 == `FUNCT3_ARTIH_SLT && funct7 == `FUNCT7_ARTIH_ADD) begin
//SLT
if ($signed(in1_pyri) < $signed(in2_pyri)) begin
rdata_pyro = 64'd1;
end else begin
rdata_pyro = 64'd0;
end
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_ARITH && funct3 == `FUNCT3_ARTIH_SLT && funct7 == `FUNCT7_ARTIH_ADD) begin
//SLTU
if (in1_pyri < in2_pyri) begin
rdata_pyro = 64'd1;
end else begin
rdata_pyro = 64'd0;
end
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_ARITH && funct3 == `FUNCT3_ARTIH_XOR && funct7 == `FUNCT7_ARTIH_ADD) begin
//XOR
rdata_pyro = $signed(in1_pyri) ^ $signed(in2_pyri);
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_ARITH && funct3 == `FUNCT3_ARTIH_SLL && funct7 == `FUNCT7_ARTIH_ADD) begin
//SRL
rdata_pyro = in1_pyri >> in2_pyri[4:0];
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_ARITH && funct3 == `FUNCT3_ARTIH_SRA && funct7 == `FUNCT7_ARTIH_SUB) begin
//SRA
rdata_pyro = $signed(in1_pyri) >>> in2_pyri[4:0];
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_ARITH && funct3 == `FUNCT3_ARTIH_OR && funct7 == `FUNCT7_ARTIH_ADD) begin
//OR
rdata_pyro = $signed(in1_pyri) | $signed(in2_pyri);
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_ARITH && funct3 == `FUNCT3_ARTIH_AND && funct7 == `FUNCT7_ARTIH_ADD) begin
//AND
rdata_pyro = $signed(in1_pyri) & $signed(in2_pyri);
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_THEI && funct3 == `FUNCT3_ARIIH_SLLI && funct7 == `FUNCT7_ARTIH_ADD) begin
//SLLI
rdata_pyro = in1_pyri << inst_pyri[24:20];
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_THEI && funct3 == `FUNCT3_ARIIH_SRLI && funct7 == `FUNCT7_ARTIH_ADD) begin
//SRLI
rdata_pyro = in1_pyri >> inst_pyri[24:20];
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_THEI && funct3 == `FUNCT3_ARITH_SRAI && funct7 == `FUNCT7_ARTIH_SUB) begin
//SRAI
rdata_pyro = $signed(in1_pyri) >>> $signed(inst_pyri[24:20]);
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
// 64-bit shifts
end else if (op == `OP_THEI64 && funct3 == `FUNCT3_ARIIH_SLLI && funct7 == `FUNCT7_ARTIH_ADD) begin
//SLLI
temp2 = in1_pyri << inst_pyri[26:20];
temp = temp2[31:0];
rdata_pyro = { {32{temp[31]} },temp}; //sign extention.
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_THEI64 && funct3 == `FUNCT3_ARIIH_SRLI && funct7 == `FUNCT7_ARTIH_ADD) begin
//SRLI
temp2 = in1_pyri >> inst_pyri[26:20];
temp = temp2[31:0];
rdata_pyro = { {32{temp[31]} },temp}; //sign extention.
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_THEI64 && funct3 == `FUNCT3_ARITH_SRAI && funct7 == `FUNCT7_ARTIH_SUB) begin
//SRAI
temp2 = $signed(in1_pyri) >>> inst_pyri[26:20];
temp = temp2[31:0];
rdata_pyro = { {32{temp[31]} },temp}; //sign extention.
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
///////////////
end else if (op == `OP_THEI && funct3 == `FUNCT3_ARTIH_ADDI) begin
//ADDI
rdata_pyro = $signed(in1_pyri) + $signed({ {52{I_immediate[11]} },I_immediate});
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_THEI && funct3 == `FUNCT3_ARTIH_SLTI) begin
//SLTI
if ($signed(in1_pyri) < $signed({ {52{I_immediate[11]} },I_immediate})) begin
rdata_pyro = 64'd1;
end else begin
rdata_pyro = 64'd0;
end
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_THEI && funct3 == `FUNCT3_ARTIH_SLTIU) begin
//SLTIU
if (in1_pyri < { {52{I_immediate[11]} },I_immediate}) begin
rdata_pyro = 64'd1;
end else begin
rdata_pyro = 64'd0;
end
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_THEI && funct3 == `FUNCT3_ARTIH_XORI) begin
//XORI
rdata_pyro = $signed(in1_pyri) ^ $signed({ {52{I_immediate[11]} },I_immediate});
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_THEI && funct3 == `FUNCT3_ARTIH_ORI) begin
//ORI
rdata_pyro = $signed(in1_pyri) | $signed({ {52{I_immediate[11]} },I_immediate});
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_THEI && funct3 == `FUNCT3_ARTIH_ANDI) begin
//ANDI
rdata_pyro = $signed(in1_pyri) & $signed({ {52{I_immediate[11]} },I_immediate});
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_ADDIW && funct3 == `FUNCT3_ARTIH_ADDIW) begin
//ADDIW
temp2 = $signed(in1_pyri) + $signed({ {52{I_immediate[11]} },I_immediate});
temp = temp2[31:0];
rdata_pyro = { {32{temp[31]} },temp}; //sign extention.
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_ADDIW && funct3 == `FUNCT3_ARTIH_SLLIW && funct7 == `FUNCT7_ARTIH_ADD) begin
//SLLIW
temp2 = in1_pyri << inst_pyri[24:20];
temp = temp2[31:0];
rdata_pyro = { {32{temp[31]} },temp}; //sign extention.
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_ADDIW && funct3 == `FUNCT3_ARTIH_SRLIW && funct7 == `FUNCT7_ARTIH_ADD) begin
//SRLIW
temp2 = in1_pyri >> inst_pyri[24:20];
temp = temp2[31:0];
rdata_pyro = { {32{temp[31]} },temp}; //sign extention.
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_ADDIW && funct3 == `FUNCT3_ARTIH_SRAIW && funct7 == `FUNCT7_ARTIH_SUB) begin
//SRAIW
temp2 = $signed(in1_pyri) >>> inst_pyri[24:20];
temp = temp2[31:0];
rdata_pyro = { {32{temp[31]} },temp}; //sign extention.
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_ADDW && funct3 == `FUNCT3_ARTIH_ADDW && funct7 == `FUNCT7_ARTIH_ADD) begin
//ADDW
temp2 = $signed(in1_pyri) + $signed(in2_pyri);
temp = temp2[31:0];
rdata_pyro = { {32{temp[31]} },temp}; //sign extention.
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_ADDW && funct3 == `FUNCT3_ARTIH_SUBW && funct7 == `FUNCT7_ARTIH_SUB) begin
//SUBW
temp2 = $signed(in1_pyri) - $signed(in2_pyri);
temp = temp2[31:0];
rdata_pyro = { {32{temp[31]} },temp}; //sign extention.
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_ADDW && funct3 == `FUNCT3_ARTIH_SLLW && funct7 == `FUNCT7_ARTIH_ADD) begin
//SLLW
temp2 = in1_pyri << in2_pyri[4:0];
temp = temp2[31:0];
rdata_pyro = { {32{temp[31]} },temp}; //sign extention.
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_ADDW && funct3 == `FUNCT3_ARTIH_SRLW && funct7 == `FUNCT7_ARTIH_ADD) begin
//SRLW
temp2 = in1_pyri >> in2_pyri[4:0];
temp = temp2[31:0];
rdata_pyro = { {32{temp[31]} },temp}; //sign extention.
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_ADDW && funct3 == `FUNCT3_ARTIH_SRAW && funct7 == `FUNCT7_ARTIH_SUB) begin
//SRAW
temp2 = $signed(in1_pyri) >>> in2_pyri[4:0];
temp = temp2[31:0];
rdata_pyro = { {32{temp[31]} },temp}; //sign extention.
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
// Branch instructions
end else if (op == `OP_B && funct3 == `FUNCT3_B_BEQ) begin
//BEQ
if ($signed(in1_pyri) == $signed(in2_pyri)) begin
branch_pc_pyro = $signed(pc_pyri) + $signed({ { 51{B_immediate[12]} },B_immediate,1'b0});
end else begin
branch_pc_pyro = $signed(pc_pyro) + 64'd4;
end
branch_pc_valid_pyro = all_valid;
rdata_valid_pyro = 1'b0;
raddr_valid_pyro = 1'b0;
end else if (op == `OP_B && funct3 == `FUNCT3_B_BNE) begin
//BNE
if (in1_pyri != in2_pyri) begin
branch_pc_pyro = $signed(pc_pyri) + $signed({ { 51{B_immediate[12]} },B_immediate,1'b0});
end else begin
branch_pc_pyro = $signed(pc_pyro) + 64'd4;
end
branch_pc_valid_pyro = all_valid;
rdata_valid_pyro = 1'b0;
raddr_valid_pyro = 1'b0;
end else if (op == `OP_B && funct3 == `FUNCT3_B_BLT) begin
//BLT
if ($signed(in1_pyri) < $signed(in2_pyri)) begin
branch_pc_pyro = $signed(pc_pyri) + $signed({ { 51{B_immediate[12]} },B_immediate,1'b0});
end else begin
branch_pc_pyro = $signed(pc_pyro) + 64'd4;
end
branch_pc_valid_pyro = all_valid;
rdata_valid_pyro = 1'b0;
raddr_valid_pyro = 1'b0;
end else if (op == `OP_B && funct3 == `FUNCT3_B_BGE) begin
//BGE
if ($signed(in1_pyri) >= $signed(in2_pyri)) begin
branch_pc_pyro = $signed(pc_pyri) + $signed({ { 51{B_immediate[12]} },B_immediate,1'b0});
end else begin
branch_pc_pyro = $signed(pc_pyro) + 64'd4;
end
branch_pc_valid_pyro = all_valid;
rdata_valid_pyro = 1'b0;
raddr_valid_pyro = 1'b0;
end else if (op == `OP_B && funct3 == `FUNCT3_B_BLTU) begin
//BLTU
if ($unsigned(in1_pyri) < $unsigned(in2_pyri)) begin
branch_pc_pyro = $signed(pc_pyri) + $signed({ { 51{B_immediate[12]} },B_immediate,1'b0});
end else begin
branch_pc_pyro = $signed(pc_pyro) + 64'd4;
end
branch_pc_valid_pyro = all_valid;
rdata_valid_pyro = 1'b0;
raddr_valid_pyro = 1'b0;
end else if (op == `OP_B && funct3 == `FUNCT3_B_BGEU) begin
//BGEU
if ($unsigned(in1_pyri) >= $unsigned(in2_pyri)) begin
branch_pc_pyro = $signed(pc_pyri) + $signed({ { 51{B_immediate[12]} },B_immediate,1'b0});
end else begin
branch_pc_pyro = $signed(pc_pyro) + 64'd4;
end
branch_pc_valid_pyro = all_valid;
rdata_valid_pyro = 1'b0;
raddr_valid_pyro = 1'b0;
end else if (op == `OP_LUI) begin
//LUI
temp = {inst_pyri[31:12],12'd0};
rdata_pyro = { {32{temp[31]} },temp}; //sign extention.
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_AUIPC) begin
//AUIPC
temp = {inst_pyri[31:12],12'd0};
rdata_pyro = $signed(pc_pyri) + {{32{temp[31]} },temp}; //sign extend and add.
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_JAL) begin
//JAL
branch_pc_valid_pyro = 1'b0;
rdata_pyro = $signed(pc_pyri) + 64'd4;
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_JALR && funct3 == `FUNCT3_JALR) begin
//JALR
branch_pc_pyro = $signed(in1_pyri) + { {52{I_immediate[11]} },I_immediate};
branch_pc_valid_pyro = all_valid;
rdata_pyro = $signed(pc_pyri) + 64'd4;
raddr_pyro = {59'b0,inst_pyri[11:7]};
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
// Load instructions
end else if (op == `OP_LD && funct3 == `FUNCT3_LD) begin
//LD
raddr_pyro = {59'd0,inst_pyri[11:7]};
raddr_valid_pyro = all_valid;
rdata_pyro = $signed(in1_pyri) + $signed({ {52{I_immediate[11]} },I_immediate});
rdata_valid_pyro = all_valid;
end else if (op == `OP_LD && funct3 == `FUNCT3_LB) begin
//LB
raddr_pyro = {59'd0,inst_pyri[11:7]};
raddr_valid_pyro = all_valid;
rdata_pyro = $signed(in1_pyri) + $signed({ {52{I_immediate[11]} },I_immediate});
rdata_valid_pyro = all_valid;
end else if (op == `OP_LD && funct3 == `FUNCT3_LH) begin
//LH
raddr_pyro = {59'd0,inst_pyri[11:7]};
raddr_valid_pyro = all_valid;
rdata_pyro = $signed(in1_pyri) + $signed({ {52{I_immediate[11]} },I_immediate});
rdata_valid_pyro = all_valid;
end else if (op == `OP_LD && funct3 == `FUNCT3_LW) begin
//LW
raddr_pyro = {59'd0,inst_pyri[11:7]};
raddr_valid_pyro = all_valid;
rdata_pyro = $signed(in1_pyri) + $signed({ {52{I_immediate[11]} },I_immediate});
rdata_valid_pyro = all_valid;
end else if (op == `OP_LD && funct3 == `FUNCT3_LBU) begin
//LBU
raddr_pyro = {59'd0,inst_pyri[11:7]};
raddr_valid_pyro = all_valid;
rdata_pyro = in1_pyri + { {52{I_immediate[11]} },I_immediate};
rdata_valid_pyro = all_valid;
end else if (op == `OP_LD && funct3 == `FUNCT3_LHU) begin
//LHU
raddr_pyro = {59'd0,inst_pyri[11:7]};
raddr_valid_pyro = all_valid;
rdata_pyro = in1_pyri + { {52{I_immediate[11]} },I_immediate};
rdata_valid_pyro = all_valid;
end else if (op == `OP_LD && funct3 == `FUNCT3_LWU) begin
//LWU
raddr_pyro = {59'd0,inst_pyri[11:7]};
raddr_valid_pyro = all_valid;
rdata_pyro = in1_pyri + { {52{I_immediate[11]} },I_immediate};
rdata_valid_pyro = all_valid;
// Store instructions
end else if (op == `OP_SD && funct3 == `FUNCT3_SD) begin
//SD
rdata_pyro = $signed(in2_pyri);
raddr_pyro = $signed(in1_pyri) + $signed({ {52{inst_pyri[31]} },inst_pyri[31:25],inst_pyri[11:7]});
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_SD && funct3 == `FUNCT3_SB) begin
//SB
rdata_pyro = {{56{in2_pyri[7]}},in2_pyri[7:0]};
raddr_pyro = $signed(in1_pyri) + $signed({ {52{inst_pyri[31]} },inst_pyri[31:25],inst_pyri[11:7]});
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_SD && funct3 == `FUNCT3_SH) begin
//SH
rdata_pyro = {{48{in2_pyri[7]}},in2_pyri[15:0]};
raddr_pyro = $signed(in1_pyri) + $signed({ {52{inst_pyri[31]} },inst_pyri[31:25],inst_pyri[11:7]});
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end else if (op == `OP_SD && funct3 == `FUNCT3_SW) begin
//SW
rdata_pyro = {{32{in2_pyri[7]}},in2_pyri[31:0]};
raddr_pyro = $signed(in1_pyri) + $signed({ {52{inst_pyri[31]} },inst_pyri[31:25],inst_pyri[11:7]});
rdata_valid_pyro = all_valid;
raddr_valid_pyro = all_valid;
end
end
end
endmodule
- Quote paper
- Alexios Iosif Kotsis (Author), 2018, Verilog Methods and Practical Analysis on a Running Cycle Project, Munich, GRIN Verlag, https://www.grin.com/document/444990
-
Upload your own papers! Earn money and win an iPhone X. -
Upload your own papers! Earn money and win an iPhone X. -
Upload your own papers! Earn money and win an iPhone X. -
Upload your own papers! Earn money and win an iPhone X. -
Upload your own papers! Earn money and win an iPhone X. -
Upload your own papers! Earn money and win an iPhone X. -
Upload your own papers! Earn money and win an iPhone X. -
Upload your own papers! Earn money and win an iPhone X. -
Upload your own papers! Earn money and win an iPhone X. -
Upload your own papers! Earn money and win an iPhone X. -
Upload your own papers! Earn money and win an iPhone X. -
Upload your own papers! Earn money and win an iPhone X. -
Upload your own papers! Earn money and win an iPhone X. -
Upload your own papers! Earn money and win an iPhone X. -
Upload your own papers! Earn money and win an iPhone X. -
Upload your own papers! Earn money and win an iPhone X. -
Upload your own papers! Earn money and win an iPhone X. -
Upload your own papers! Earn money and win an iPhone X. -
Upload your own papers! Earn money and win an iPhone X. -
Upload your own papers! Earn money and win an iPhone X.