当前位置:网站首页>Verilog implementation of a simple legv8 processor [4] [explanation of basic knowledge and module design of single cycle implementation]

Verilog implementation of a simple legv8 processor [4] [explanation of basic knowledge and module design of single cycle implementation]

2022-07-07 14:10:00 Stool flower*

One 、 Preface

The original idea was to explain the principle of each module implemented in a single cycle , Then open other blogs to explain the various modules Verilog Design , But I thought about it later , This is inconvenient for everyone to understand , You may also forget the function of the module to be implemented after seeing it . So the explanation mode is modified to : Side talk principle , And show you Verilog Realization , This can also deepen understanding . Besides , In addition to explaining the module design idea , We will also use some in the design process Verilog Grammar and norms Let me also explain to you ( These contents are based on Watch your step These four words begin , And highlighted , like this : Watch your step ).

This blog explains the principles and techniques needed to implement a processor . Of course, the current design is only a single cycle implementation of the processor , There will be more real assembly lines in the future LEGv8 Realization . The difference between assembly line and single cycle will also be explained later .

notes : Because I don't want to share P Too much , So I plan to write a blog about single cycle implementation , And there will be a lot of code in it , This will lead to a lot of content , So it may take you a long time to learn one .

Two 、 Module principle and design

( One ) Command analysis

Now we are going to complete a kind of inclusion LEGv8 An implementation of the core instruction set , This implementation is for A simple LEGv8 The processor Verilog Realization 【 One 】【 Introduction to the experiment 】 Factorial and sorting algorithms mentioned in to select instructions to complete . A simple LEGv8 The processor Verilog Realization 【 Two 】【 Basic knowledge and experimental analysis 】 This blog explains the corresponding two algorithms to be implemented LEGv8 Program , Use of LEGv8 The instructions are summarized below :

The instructions used in the above two functions are :
ADD、LSL、BR、ADDI、SUBI、SUBIS、STUR、LDUR、B、BL、B.GE、B.LT、B.LE、MUL、CMP、MOV. among MOV and CMP It belongs to pseudo instruction . Combine the above instructions into a new instruction set as follows :

InstructionOpcodeOpcode Size11-bit opcode range11-bit opcode rangeInstruction Format
Startend
ADD(MOV)1000101100011112R
LSL11010011011111691R
BR11010110000111712R
SUBS(CMP)11101011000111880R
ADDI10010001001011601161I
SUBI11010001001016721673I
SUBIS11110001001019281929I
STUR11111000000111984D
LDUR11111000010111986D
B0001016160191B
BL100101611841215B
B.cond010101008672679CB

There will be MOV Instruction as ADD Instructions to implement ,CMP Instruction as SUBS Instructions to implement . In the process of implementation , In addition to the above instructions , Some other similar simple instructions are also extended , We'll talk about it when we need it .

( Two ) Implementation Overview

In the second blog , We explained LEGv8 The instruction set 6 Class instructions , Let's review it here :R type ( Arithmetic operation instruction format , Such as ADD、AND、LSL、BR etc. )、I type ( Immediate format , Such as ADDI、ORRI etc. )、D type ( Data transfer format , Such as LDUR、STUR etc. )、B type ( Unconditional branch format ,B and BL)、CB type ( Conditional branch format ,B.cond、CBZ、CBNZ) and IM type ( Wide immediate format ,MOVZ、MOVK). In our experiment , Only care about the former 5 class . If you don't know, go to the second article : A simple LEGv8 The processor Verilog Realization 【 Two 】【 Basic knowledge and experimental analysis 】.

The first two steps of these instructions are the same :
1、 Program counter (PC) Point to the storage unit where the instruction is located , And take out the instructions .
2、 Through the contents of the instruction field , Select to read one or two registers . about LDUR and CBZ Instructions , Just read one register , Most other instructions need to read two registers .

After these two steps , The steps taken to complete the instruction depend on the specific instruction type . Fortunately, , For three instruction types ( Storage access 、 Arithmetic logic 、 Branch ) For each category , Its action is roughly the same , It has nothing to do with specific instructions .

LEGv8 The simplicity and regularity of the instruction set make the execution of many instructions very similar , Thus, the implementation process is simplified . for example , Except for unconditional branches ( Jump ) All instructions except instructions , After reading the register , Use arithmetic logic units (ALU). For storing access instructions ALU Calculate the address , Arithmetic logic instructions use ALU Perform the operation , Branch instructions use ALU And 0 Compare .

In the use of ALU after , The actions required to complete different instructions are different . Memory access instructions require access to memory in order to read or store data . Arithmetic logic instruction or fetching instruction will come from ALU Or the data of the memory is written into the register . Last , For conditional branch instructions , You need to decide whether to change the address of the next instruction according to the comparison result ; If not modified , Will PC Add 4 Get the next instruction in the order .

Although there are differences in the execution between instructions , But we still divide the execution process of instructions into 5 Stages , Namely : Fingering (Instruction Fetch,IF)、 decoding (Instruction Decode,ID)、 perform (Executation,EX)、 Storage (Memory,MEM) And write back (Write Back,WB). this 5 Three stages run through our design , It's very important .

This design aims to achieve CPU The top layer is shown in the figure below :
 Insert picture description here
chart 1 LEGv8 CPU top floor

The picture above shows LEGv8 View of implementation , The functional units and their interconnection are described . The execution of all instructions begins with the use of program counters PC Get the address of the instruction in the instruction memory , namely Fingering IF. After getting the instruction , The register operand used by the instruction is determined by the corresponding field in the instruction ( decoding ID), After getting the register operand , It can be used to calculate the memory address ( For access class instructions ), Or calculate the result of arithmetic operation ( For integer arithmetic logic class instructions ), Or with 0 Compare ( For branch class instructions )( perform EX). If the instruction is an arithmetic logic instruction ,ALU The result of must be written back to the register ( Write back to WB). If it is an access class instruction ,ALU The result of can be used as the address of read-write memory ( Storage MEM).ALU Or the result of the memory can be written back to the register file ( Write back to WB). Branch instructions need to use ALU The output of determines the next instruction address , The address may be from ALU( stay ALU Lieutenant general PC Value is added to the branch offset ), It may also come from an adder ( At present PC It's worth adding 4)( Put this stage in the design Storage phase MEM level , Because we need to consider the subsequent risk detection ). The arrow on the line connecting the functional units is used to indicate the direction of information flow .

Each stage is marked with different colors in the figure .

Besides , Of the functional units in the figure control It depends on the instruction type . for example , load Instruction read data memory , and store Instruction write data memory . Register files are written only when fetching instructions and arithmetic logic instructions . Obviously ,ALU Perform different operations according to different instructions ( It will be described later ALU Design details of ). Similar to multiplexer , These operations are determined by the control signal , The control signal is determined by some fields of the instruction . The control unit in the figure (control unit) Take instructions as input , Decide how to set the control signals of the functional unit and the two multi selectors .

( 3、 ... and ) Module design

1、 The header file

Before explaining the design of other modules , Let's first explain the header files required by each module , In the code common.vh.
Watch your step : In this design , I put all the information I need into A header file in . But in fact , When you design , You can according to the needs of the module , Put the required content into different files , That is, multiple header files .( Be similar to C Language , You can write a header file per module ).
common.vh as follows :

`ifndef COMMON_HEADER
`define COMMON_HEADER

//*******************************
// Definition of data type
//*******************************

// Size of a WORD
`define WORD      64
// Size of a HALF_WORD
`define HALF_WORD 32
// Length of instructions
`define INST_SIZE `HALF_WORD

//*******************************
// Definition of file path
//*******************************

/
// Single Cycle Factorial
// Instruction memory file 
`define SINGLE_CYCLE_FACT_INST_FILE "data/factorial/SingleCycle/inst_mem.txt"
// Data file
`define SINGLE_CYCLE_FACT_DATA_FILE  "data/factorial/SingleCycle/data_mem.txt"


// Pipeline Factorial
// Instruction memory file
`define PIPELINE_FACT_INST_FILE "data/factorial/Pipeline/inst_mem.txt"
// Data file
`define PIPELINE_FACT_DATA_FILE  "data/factorial/Pipeline/data_mem.txt"

/
// Single Cycle Bubble Sort
// Instruction memory file
`define SINGLE_CYCLE_SORT_INST_FILE "data/bubble_sort/SingleCycle/inst_mem.txt"
// Data file
`define SINGLE_CYCLE_SORT_DATA_FILE  "data/bubble_sort/SingleCycle/data_mem.txt"
// Data file TB sorted
`define SINGLE_CYCLE_SORT_DATA_FILE_TB  "data/bubble_sort/SingleCycle/data_mem_tb_sorted.txt"

// Pipeline Bubble Sort
// Instruction memory file
`define PIPELINE_SORT_INST_FILE "data/bubble_sort/Pipeline/inst_mem.txt"
// Data file
`define PIPELINE_SORT_DATA_FILE  "data/bubble_sort/Pipeline/data_mem.txt"
// Data file TB sorted
`define PIPELINE_SORT_DATA_FILE_TB  "data/bubble_sort/Pipeline/data_mem_tb_sorted.txt"

/
// Bubble sort test 0
// Instruction memory file
`define SORT_INST_FILE "data/bubble_sort/0/inst_mem.txt"
// Data file
`define SORT_DATA_FILE  "data/bubble_sort/0/data_mem.txt"

/
// Test
// Instruction memory file
`define TEST_INST_FILE "data/test/inst_mem.txt"
// Data memory for test
`define TEST_DATA_FILE "data/test/data_mem.txt"

//*******************************
// Definition of instruction opcode
//*******************************

`define ADD     11'b10001011000
`define ADDI    11'b1001000100?
`define ADDS    11'b10101011000
`define ADDIS   11'b1011000100?
`define AND     11'b10001010000
`define ANDI    11'b1001001000?
`define ANDS    11'b11101010000
`define ANDIS   11'b1111001000?
`define B       11'b000101?????
`define BL      11'b100101?????
`define BR      11'b11010110000
`define BCOND   11'b01010100???
`define CBZ     11'b10110100???
`define CBNZ    11'b10110101???
`define CMPI    11'b1100001110?
`define DIV     11'b10011010110
`define EOR     11'b11001010000
`define EORI    11'b1101001000?
`define LDURS   11'b10111100010
`define STURS   11'b10111100000
`define LDURD   11'b11111100010
`define STURD   11'b11111100000
`define LDA     11'b10010110101
`define LDUR    11'b11111000010
`define LDURB   11'b00111000010
`define LDURH   11'b01111000010
`define LDURSW  11'b10111000100
`define LSL     11'b11010011011
`define LSR     11'b11010011010
`define MOVK    11'b111100101??
`define MOVZ    11'b110100101??
`define MUL     11'b10011011000
`define ORR     11'b10101010000
`define ORRI    11'b1011001000?
`define STUR    11'b11111000000
`define STURB   11'b00111000000
`define STURH   11'b01111000000
`define STURW   11'b10111000000
`define SUB     11'b11001011000
`define SUBI    11'b1101000100?
`define SUBS    11'b11101011000
`define SUBIS   11'b1111000100?

//*******************************
// Conditional branch rt values
//*******************************

`define BCOND_NV  5'b00000 // Always, NV exists only to provide a valid disassembly of the ‘00000b’ encoding, and otherwise behaves identically to AL.
`define BCOND_EQ  5'b00001 // Equal, Z == 1
`define BCOND_NE  5'b00010 // Not equal, Z == 0
`define BCOND_CS  5'b00011 // AKA HS, Unsigned higher or same( Carry set ), C == 1
`define BCOND_LE  5'b00100 // Signed less than or equal, !( Z == 0 && N == V )
`define BCOND_CC  5'b00101 // AKA LO, unsigned lower( Carry clear ), C == 0
`define BCOND_MI  5'b00111 // Minus( negative ), N == 1
`define BCOND_PL  5'b01000 // Plus( positive or zero ), N == 0
`define BCOND_VS  5'b01001 // Overflow set , V == 1
`define BCOND_VC  5'b01010 // Overflow clear, V == 0
`define BCOND_HI  5'b01011 // Unsigned higher, C == 1 && Z == 0
`define BCOND_LS  5'b01100 // Unsigned lower or same, !( C == 1 && Z == 0 )
`define BCOND_GE  5'b01101 // Signed greater than or equal, N == V
`define BCOND_LT  5'b01110 // Signed less than, N != V
`define BCOND_GT  5'b01111 // Signed greater than, Z == 0 && N == V
`define BCOND_AL  5'b11111 // Always

//*******************************
// Conditional branch ops
//*******************************

`define BCOND_OP_NONE    3'b000
`define BCOND_OP_BRANCH  3'b001
`define BCOND_OP_COND    3'b010
`define BCOND_OP_ZERO    3'b011
`define BCOND_OP_NZERO   3'b100
`define BCOND_OP_ALU     3'b101
`define BCOND_OP_NOINC   3'b110

//*******************************
// ALU control signals
//*******************************

`define ALU_AND   4'b0000 
`define ALU_OR    4'b0001 
`define ALU_ADD   4'b0010 
`define ALU_MUL   4'b0011 
`define ALU_SUB   4'b0110
`define ALU_PASS  4'b0111
`define ALU_NOR   4'b1100
`define ALU_XOR   4'b0100
`define ALU_LSL   4'b1000
`define ALU_LSR   4'b1001
`define ALU_NONE  4'b1111

`define TB_BEGIN \
    $display("\n========= BEGIN TESTBENCH %m =========\n");
    
`define TB_END \
    #`CYCLE $display("\n========== END TESTBENCH %m =========\n");
    
`define CYCLE 10
`define HALF_CYCLE (`CYCLE/2)

`endif 

The first thing that catches my eye is these two sentences :

`ifndef COMMON_HEADER
`define COMMON_HEADER
......
`endif

Watch your step : Often write C/C++ You should know , This is for Prevent duplicate inclusion of header files .


Continue to look at the code , This format is basically followed :

//*******************************
//  notes 
//*******************************
 Content ... //  notes 

Watch your step : You can also write code in this format in the future , Let's start with a comment to clarify what the following content is , Then write the specific content , The specific content can be followed by some more detailed comments . After all, the saying goes well : A month after the code , Only you and God can understand ; After three months , Only God can understand ; In three months , It's hard for anyone to come . So we must develop the good habit of writing notes !!!


Let's introduce the contents of this header file :
Definition of data type Here are some definitions of data bit width , What we want to achieve LEGv8 The processor is 32 Bit instruction , But it is 64 Address of bit , So here , Define a word as 64 position , Half word for 32 position . At the same time, the instruction bit width is defined as half word .


Definition of file path Here are some definitions of file paths , It defines the instruction file and data file that we finally use .
Watch your step : If we use something many times in our code , You might as well simplify your code by defining macros , Increase readability .


Definition of instruction opcode Here is LEGv8 The opcode of each instruction in the instruction set opcode, In fact, we don't need to define so many instruction opcodes , Just define the instructions used . But in order to facilitate the subsequent instruction expansion , So I have defined most of the instruction opcodes here .opcode It's not our own definition , You can find it directly in the textbook , Open the English textbook , Turn to the penultimate page and you will see :
 Insert picture description here

Watch your step : A closer look at the code reveals , about opcode No 11 Bit instructions , A lot is used in the definition ???, It means that you don't care about these bits .


Conditional branch rt values The following is the conditional branch judgment code , be used for B.cond The command determines whether a jump is required . These definitions can be defined by human assignment , But in fact ,ARMv8 The processor has already been defined :
 Insert picture description here

The picture above is what I found on the Internet ARM_v8_Instruction_Set_Architecture_(Overview).pdf Found in , Interested students can search by themselves , But this pdf It doesn't help us much , So I didn't put it in the online disk . The picture above is enough .

Careful students will find that the definition in my code is different from that in the above figure , Yes , I use my own definition hhh, It's not very standard , Students in need can try to change . And I use it here 5 To define , Mainly because B.cond Directive rt yes 5 Bit , Just match .( what ? You ask me this and rt What does it matter ? I didn't take a good look at it , A simple LEGv8 The processor Verilog Realization 【 Two 】【 Basic knowledge and experimental analysis 】 This article explains B.cond It was said that , Forget the students go back to have a look ).


Conditional branch ops It mainly defines some values used to judge the type of conditional jump . This will be explained in detail later when we talk about code design .


ALU control signals Here are some definitions ALU Control signals , control ALU Whether to perform addition, subtraction, multiplication and division or what operation .


Finally, some TB Macro definition in , Convenient operation .

2、 Multiplexer module

Explain the header file , Go back and look at the picture 1. In the figure 1 There are several modules found in :
 Insert picture description here
 Insert picture description here
The input data of this module comes from two or more different sources . for example , write in PC The value of may come from one of the two adders , The data written to the register file may come from ALU Or data storage , and ALU The second input of may come from an immediate field in a register or instruction . actually , These data lines cannot be simply connected directly , A logical unit must be added to select one from different data sources and send it to the target unit .

This selection operation can usually be performed by a device called a multiplexer (multiplexor) The device is complete , Although this unit is called data selector (data selector) Maybe more appropriate . The multiplexer selects different inputs by setting the control signal , The control signal is mainly set according to the information contained in the current execution instruction .

From the picture 1 You can see , We actually use two multiplexers , They are two choice one multi-channel selector and four choice one multi-channel selector , We go through MUX2 and MUX4 Express . about MUX2 Come on , The input has two data signals , And a control signal , The output is the selected data , So the control signal only needs 1 position ( adopt 0 and 1 choice ) that will do .MUX4 The input of is 4 Input data , A control signal , The output is also a selected data , So the control signal needs 2 position ( Through the combination of these two signals, they are 00/01/10/11) Choose . Please note that the number of digits of input data mentioned above is not specially emphasized , So theoretically, it can be any bit , No special requirements , But the number of bits of the selected signal is generally fixed .

MUX2 Of Verilog The code is as follows ( The file named mux2.v):

`timescale 1ns/1ps

//******************************************************************
//
//*@File Name: mux2.v
//
//*@File Type: verilog
//
//*@Version : 0.0
//
//*@Author : Zehua Dong, SIGS
//
//*@E-mail : [email protected]
//
//*@Date : 2022/3/28 22:53:07
//
//*@Function : 2-1 multiplexer.
//
//******************************************************************

//
// Header file
`include "common.vh"

//
// Module
module mux2 #( 
  parameter SIZE = `WORD )(
  a    ,              
  b    ,        
  sel  ,               
  out   
  );

  input   [SIZE - 1 : 0]   a  ;                   
  input   [SIZE - 1 : 0]   b  ;                 
  input                    sel;                   
  output  [SIZE - 1 : 0]   out;                   

  wire    [SIZE - 1 : 0]   a  ;                   
  wire    [SIZE - 1 : 0]   b  ;                 
  wire                     sel;                   
  wire    [SIZE - 1 : 0]   out;                   

  assign out = sel ? b : a;

endmodule

adopt GVIM Write Verilog Our process is A simple LEGv8 The processor Verilog Realization 【 3、 ... and 】【 Tool usage and programming specifications 】 It's been explained in , So I won't repeat it here .


Watch your step : The first line is `timescale 1ns/1ps, This sentence is very important , Defines the step size and accuracy of your simulation , It is suggested that each module should write this sentence . Specific understanding can be seen : Yes `timescale In depth understanding of .
Watch your step : When writing code, , First, give the comment header at the beginning , Indicate the author 、Email、 File modification history and other information . These do not require manual tapping , I'm explaining GVIM My template is given when the template , You can use it directly . reference :gvim【 Two 】【ab Command rapid production verilog Templates 】.
Watch your step : Look at the code format , First include the header file , Then when writing module ports, try to make one port in one line , And align , Writing like this will help you instantiate later , In addition, it can also clearly show which ports you have , You can also easily add comments after each port . Try to concentrate the ports when writing , What does that mean , Write the input port first , Then write the output port , For example, the following :

module mux2 #( 
  parameter SIZE = `WORD )(
  a    ,              
  b    ,        
  sel  ,               
  out   
  );

a, b, sel It's all input , Wrote together ,out It's output , Wrote last . Of course, this is not fixed , It's just my habit , You can adjust according to your own needs .

Careful students will find that the commas behind the ports above are Column alignment Of , in fact , Whether to adopt this method depends on your platform . For certain Linux Tools in , You may recognize the space as your port name , But if Windows Of Vivado perhaps ModelSim There will be no such problem . So we decide according to our own platform .

So why add so many empty column alignments , Isn't this more troublesome ? There are two answers : One is beautiful , It looks good after alignment , Suitable for obsessive-compulsive disorder , Of course, it doesn't make much difference ; Second, it is convenient for subsequent code writing , When you write input、output Column operation can be performed when , You can also perform column operations when writing instantiation modules … So I suggest alignment , Specific please see :gvim【 Two 】【ab Command rapid production verilog Templates 】 Demonstration in .

Watch your step : Besides , The above code also uses parameters parameter, This writing method can be used for parameterization , That is, the parameter value can be specified later during instantiation , Very convenient , It is recommended to master . Here we set the bit width of the input and output data to the parameter SIZE, The latter instantiation can be specified as 64bit Or other bit. There are other ways to instantiate parameters , You can baidu yourself , Don't want Baidu , It's enough to directly remember my above writing .

Watch your step : When writing ports, I suggest you follow my way of writing , That is, the module port only has a name , Do not declare input / output, bit width, etc , Such as this :

module mux2 #( 
  parameter SIZE = `WORD )(
  input [63:0] a    ,              
  input [63:0] b    ,        
  input sel  ,               
  output [63:0] out   
  );

It's OK to write like this , But some compilers may not support this writing , The type of output is also prone to error and omission , And if something goes wrong, it's hard to find it .


The format is explained , The next step is code implementation , Actually mux2 It's simple , Just one line of core statement .

assign out = sel ? b : a;

Watch your step : Here we use the trinocular operator , namely ? : , This kind of writing may be often used , It is recommended to master . It means :? Whether the preceding condition is true , Output if yes : The value in front , Otherwise output : Value after . So this code means if sel by 1, be out by b, otherwise out by a.

Of course , You can also use the following method to implement this two-way selector :

if(sel == 1'b0)
	out = a;
else
	out = b;	

This code means if sel by 0 be out by a, otherwise out by b. But there is a drawback to this writing , In judging sel by 0 The comparator is used in , That's in the code == It may be integrated into a comparator , The area occupied by the comparator is relatively large . So it can be written like this :

if(!&sel)
	out = a;
else
	out = b;	

& stay Verilog Middle means bitwise AND ,! Indicates the logical inverse , You can also use ~ According to the not . The opposite of logic means no matter sel How many , The final result can only be 1 position ; The number of digits of the result after bit reversal is the same as the original data digit .

So why is it better to write this way than to write the comparator directly ? This is because !&sel Only a NAND gate and a non gate are used , The area of these two is much smaller than that of the comparator . Of course, this is just an example of an ideal situation , In fact, the code may be optimized automatically during synthesis , But we still have to have this kind of thinking .


call ~ , A little mux2 For so long ~, But this is because we are the first code , There are many formats to talk about , The format will be introduced less later .

Let's talk about mux4:

`timescale 1ns/1ps

//******************************************************************
//*@File Name: mux4.v
//*@File Type: verilog
//*@Version : 0.0
//*@Author : Zehua Dong, SIGS
//*@E-mail : [email protected]
//*@Date : 2022/3/29 20:26:55
//*@Function : 4-1 multiplexer. 
//******************************************************************

//
// Header file
`include "common.vh"

//
// Module
module mux4 #( 
  parameter SIZE = `WORD )(
  a     ,             
  b     ,       
  c     ,      
  d     ,    
  sel   ,       
  out    
  );

  input  [SIZE - 1 : 0]           a  ;                   
  input  [SIZE - 1 : 0]           b  ;                
  input  [SIZE - 1 : 0]           c  ;                   
  input  [SIZE - 1 : 0]           d  ;                
  input  [1:0]                    sel;                   
  output [SIZE - 1 : 0]           out;                

  wire   [SIZE - 1 : 0]           a  ;                   
  wire   [SIZE - 1 : 0]           b  ;                
  wire   [SIZE - 1 : 0]           c  ;                   
  wire   [SIZE - 1 : 0]           d  ;                
  wire   [1:0]                    sel;                   
  reg    [SIZE - 1 : 0]           out;                

  always @(*) begin
    case( sel )
      2'b00: out = a;
      2'b01: out = b;
      2'b10: out = c;
      2'b11: out = d;
      default: out = 'b0;
    endcase
  end

endmodule

mux4 Design and mux2 similar , Only the input port becomes 4 Data and 1 Two bit selection signal . However, we didn't use the trinocular operator when making the selection this time , But another way of writing case.case It is a judgment structure without priority , Of course you can use it if…else…, But it is suggested to use case sentence . Specifically if…else… and case See the difference between the integrated circuits : Writing Verilog What's the trick .

Watch your step : Pay attention here case Sentences must keep up default, Otherwise, the synthesized one may be a latch , The latch will cause our function to be incorrect , So we must form good habits . also if When statements are used in combinatorial logic , Be sure to follow else sentence ; It is also recommended to follow up for temporal logic , Of course, when you are proficient in writing later , Maybe not .

notes : Here I suggest you pay attention to the official account of the above link , I didn't receive the advertising fee , I don't know him , But his content is very suitable for us to study , And the quality of each article is also ok , So you can see more and learn more .

(* ̄︶ ̄)~ mux4 End of explanation , What about? , Is it simple ︿( ̄︶ ̄)︿

PC modular


The difference between single cycle and pipeline

One cycle CPU Each instruction uses a longer clock cycle , And follow figure 1 The general form of . In this design , Each instruction starts execution on a clock edge , And finish at the next clock edge . Although this method is easy to understand , But it's not practical , Because the clock cycle must be extended to meet the execution time The longest instruction . After realizing the control of this simple computer , We will discuss a pipeline implementation and its complexity .

notes : It's important here , Some students can't understand the difference between single cycle and assembly line , As you can see later, the single cycle implementation process is actually used D Trigger ( for example PC Or register heap ). Some students may take it for granted that an instruction is completed in multiple cycles , Of course it's not right , Yes CPU The timing understanding of instruction execution is still not deep .


well , That's all for this section , If you have something to gain and are willing to , Please give me a compliment , Collection can also be wow ( ̄▽ ̄)~*


Blog structure arrangement

This series of blogs is divided into 5 piece :
The first chapter briefly explains some basic knowledge of processors , And clarify the experimental requirements .

The second part starts from the instruction 、 register 、 The basic knowledge needed to design the processor is explained in detail from the perspective of assembler , The assembler needed in the experiment is analyzed .

The third part is about numbers IC Some tools needed for design and usage , And explained some programming specifications .

The fourth part is mainly for single cycle CPU The basic theory and module design of , Talking about Verilog When it's done , Incidentally, I talked about many programming specifications .


Other blogs in this series

  1. A simple LEGv8 The processor Verilog Realization 【 One 】【 Introduction to the experiment 】
  2. A simple LEGv8 The processor Verilog Realization 【 Two 】【 Basic knowledge and experimental analysis 】
  3. A simple LEGv8 The processor Verilog Realization 【 3、 ... and 】【 Tool usage and programming specifications 】
  4. A simple LEGv8 The processor Verilog Realization 【 Four 】【 Basic knowledge of single cycle implementation and explanation of module design 】

Source download

lijyhh/LEGv8


Reference material

  1. 《MK.Computer.Organization.and.Design.The.Hardware.Software.Interface.ARM.Edition》

Download resources

 link :https://pan.baidu.com/s/1dtpFTsJ5fdEmnPDyX66U1Q 
 Extraction code :b26b
原网站

版权声明
本文为[Stool flower*]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207071210414462.html