W2 SystemVerilog Part2 EN — Transcript
Full transcript
- 0:02So, then we can switch to English,
- 0:04right?
- 0:06Okay. Welcome.
- 0:10Did you understand that? No problem? Did
- 0:13you understand fully?
- 0:15Is there any question?
- 0:19Okay, these are for the sequential and
- 0:22compilation logic.
- 0:24And then now we now we are going to
- 0:26switch the blocking and non-blocking
- 0:27assignments.
- 0:28Uh
- 0:30There are two type of assignment
- 0:32statements in System Verilog. One of
- 0:34them is blocking and other one is
- 0:36non-blocking. There is a small
- 0:38difference between them. Not small, by
- 0:39the way. It is very important concept.
- 0:42Uh if you
- 0:44describing it as a smaller than equal,
- 0:47it's a non-blocking assignment. If it is
- 0:49equal, blocking assignment.
- 0:51In here, I didn't mention, but
- 0:54as you
- 0:55can notice, this is a different
- 0:58assignment statement when you look at
- 1:00the
- 1:01combinational ones. Combinational one is
- 1:03just equal,
- 1:04but in sequential ones, while assigning,
- 1:07I use
- 1:08less than and equal sign.
- 1:12So,
- 1:14in here,
- 1:16while writing a sequential statement, I
- 1:18am using
- 1:19non-blocking assignment. And while
- 1:21writing a combinational logic, while
- 1:24describing a combinational logic, I am
- 1:25using the blocking assignment.
- 1:28Non-blocking assignment means that it
- 1:30occurs simultaneously with others, as
- 1:32parallel. And blocking assignment means
- 1:35that it occurs in order it appears in
- 1:37file.
- 1:38Uh let's do an example and understand
- 1:41the difference.
- 1:42For example, in here,
- 1:44I have an example
- 1:46uh for
- 1:48non-blocking assignments. I have a
- 1:50clock. I have a D input and Q output.
- 1:52This is a just a flip-flop.
- 1:55But in here,
- 1:57when clock comes
- 2:00I am getting the D input and assigning
- 2:02it to N1. And N1, by the way, is a logic
- 2:05inside the module. We we define a logic
- 2:07signal also inside the module.
- 2:10And then this N1
- 2:13if clock comes in the rising edge of
- 2:15clock
- 2:17I am assigning D to N1 and assigning N1
- 2:20to Q.
- 2:22Okay?
- 2:23In here
- 2:25I used the non-blocking assignment. So,
- 2:27when I synthesize this circuit, what
- 2:29happens?
- 2:31This clock comes.
- 2:33Whenever this clock rises
- 2:35this D is assigned to N1.
- 2:38But, since this assignment is
- 2:40non-blocking
- 2:41these assignments occurs at the same
- 2:43time. So, this D
- 2:46sends the new value. This N1 gets the
- 2:48value of D, but this Q gets the value of
- 2:52N1, but not the
- 2:55the not not the current value, previous
- 2:57value of N1. So, this circuit
- 3:00corresponds to two flip-flops.
- 3:03When clock comes, this is clock. When
- 3:05this clock comes, D is assigned to this
- 3:09N1.
- 3:10Here is the N1 point.
- 3:12But, at the same time the previous value
- 3:15of N1 is stored in this flip-flop.
- 3:18That's why we this this code corresponds
- 3:22to two flip-flops connected as
- 3:25serial.
- 3:28This is the use of non-blocking
- 3:30assignment.
- 3:32What about the misuse?
- 3:35For example, in an always FF block, if I
- 3:37use a blocking assignment then it means
- 3:41that
- 3:42blocking assignment says that it occurs
- 3:44in order it appears in file.
- 3:47So
- 3:48in this assignment it for
- 3:50first N1 gets the value of D.
- 3:53And we are doing this assignment in
- 3:56sequential. This
- 3:58N1 gets the new value.
- 4:01And in the second
- 4:03statement, this new value is assigned to
- 4:06Q.
- 4:07So, for example,
- 4:10in the non-blocking one, the N1 was
- 4:14getting the value of D and Q was getting
- 4:16the previous value of N1. For this
- 4:18reason, we put two two flip-flops. But,
- 4:20in here,
- 4:21N1 was getting the value of D and Q was
- 4:24getting the value of N1, but the new
- 4:26value. So, it means that Q was getting Q
- 4:29is getting the value of D.
- 4:31So, then it turns to a single flip-flop.
- 4:35Because whenever clock comes, D is
- 4:38directly assigned to Q. For this reason,
- 4:41if you misuse uh
- 4:44for example, if you use a blocking
- 4:46non-blocking assignment in a always FF
- 4:48block instead of non-blocking
- 4:50assignment, it turns to a single
- 4:52flip-flop. And this is the misuse,
- 4:54because maybe you want to build this two
- 4:57flip-flop like shift register, for
- 4:59example. Uh
- 5:00but, if you use a blocking assignment in
- 5:03here,
- 5:04uh
- 5:06you can get the single flip-flop uh
- 5:09mistakenly.
- 5:11Is this clear?
- 5:15So, it's a rule that if you are building
- 5:18a logic always FF block, for example, if
- 5:20you are building a logic in always FF
- 5:23block, you have to use non-blocking
- 5:24assignment. And in always comp
- 5:26statements, you have to use blocking
- 5:28assignments. This is a general rule.
- 5:30Rule. Uh
- 5:32yeah, I can give an example, for
- 5:33example, in for the for the always comp
- 5:36block. For example, this is always comp
- 5:39block.
- 5:40And in always comp block, for example, I
- 5:43am assign I am doing D and C operation
- 5:46and assigning it to A and in the second
- 5:51row, I am for example getting not of A
- 5:54and assigning it to the D.
- 5:57In always comp block, most likely you
- 5:59want to do first end operation and after
- 6:02that you want to get the inverse of this
- 6:05end operation and assign it to D. For
- 6:07this reason, people use blocking
- 6:09assignments because in always comp
- 6:12block, we are doing it in sequentially.
- 6:14First doing this one, this operation,
- 6:16and then using the result of this
- 6:18operation as an input to the next
- 6:20operation. But in sequential blocks,
- 6:23people generally want to build
- 6:27sequential logic. Uh so,
- 6:30in here
- 6:32it is different. People wants to use for
- 6:34example use this operation, but at the
- 6:37same time people want to also do this
- 6:40operation.
- 6:41Uh not using the result of
- 6:45the
- 6:46the result of the previous flip-flop,
- 6:48for example.
- 6:50For this reason, people generally if you
- 6:52are writing a code in SystemVerilog, you
- 6:56you want to use non-blocking assignment
- 6:58in always FF statements and blocking
- 7:00assignment is in always comp blocks.
- 7:04So, it's a rule of thumb.
- 7:08And in simple combination logic, also
- 7:10people use continuous assignment. This
- 7:12is continuous assignment. This is a
- 7:14different assign-
- 7:16And more complicated combination logic,
- 7:18we use always comp and use blocking
- 7:21assignment. And in synchronous
- 7:22sequential logic in always FF statement,
- 7:25we use non-blocking assignments.
- 7:28Uh
- 7:29this is the question that you ask.
- 7:31Assign a signal in only one always
- 7:34statement or continuous assignment
- 7:36statement. Otherwise, the tool cannot
- 7:38understand and it generates
- 7:40uh wrong
- 7:42actually circuit.
- 7:46Is there any question
- 7:48until now about System Verilog?
- 7:54No question?
- 7:57Okay, we can see one more concept. In In
- 7:59this class, I will show you some
- 8:00concepts of System Verilog, but you can
- 8:03take a System
- 8:05Verilog course
- 8:07uh because I will I will try to teach
- 8:09you System Verilog in just one week, uh
- 8:11but of course System Verilog is very
- 8:13huge class.
- 8:14Uh
- 8:15huge topic. So, if you want, you can
- 8:17Google it. You can take a class on
- 8:20System Verilog.
- 8:22Uh
- 8:23but there are lots of different concepts
- 8:25of a System Verilog you you can learn.
- 8:28Uh most likely I will not teach you. For
- 8:30example, there are functions, uh there
- 8:32are package types. I will mention a
- 8:33little bit, but you can learn yourself
- 8:36also because in here I will teach in
- 8:38just in one week.
- 8:41Another concept in System Verilog is the
- 8:43module parameterization.
- 8:45Uh for example, previously
- 8:48we wrote a module mux two, and it was
- 8:51getting four-bit inputs.
- 8:54But what if for example if I want to
- 8:56write I want to write a module, and this
- 8:59module can get n-bit input?
- 9:02For example, if I give the n as
- 9:04four-bit, this module will behave as a
- 9:06four-bit mux. If I give it a eight, this
- 9:09module will behave as a eight-bit mux.
- 9:11How can I do it? Uh the method is module
- 9:14parameterization.
- 9:15In here, while defining the module,
- 9:18I am putting a dash in here, module
- 9:20module name, and I am putting a dash in
- 9:23here, and
- 9:25in here I am specifying the parameters.
- 9:28For example, in here I have a parameter.
- 9:30This parameter says that uh the module
- 9:32has a width parameter. This is integer
- 9:34parameter. If I I If I didn't write
- 9:36anything, it means it is integer
- 9:38parameter. Parameter width and it is
- 9:41default value. Default value is eight.
- 9:43And
- 9:44inside the module
- 9:46from now on, I am defining everything in
- 9:48terms of width. For example, my D0 and
- 9:51D1 inputs are
- 9:53the width size.
- 9:56Defining according to this parameter.
- 9:59And my output is in the same size and S
- 10:02is single bit input. There is no
- 10:04parameter definition in here and this is
- 10:06my output.
- 10:07So, while using this max module, while
- 10:10calling it
- 10:11then now I am also giving the parameter
- 10:15width. For example, in here
- 10:18By the way, if I want to use it as a
- 10:20with default value, default value is
- 10:22eight. You don't have to specify default
- 10:24value, but if you if you want to use it
- 10:27with your default value and if you
- 10:29define it
- 10:31then for example, you can just call the
- 10:35module
- 10:37as is as we did before.
- 10:39And since it is default value is eight,
- 10:41it it behaves as a eight-bit max.
- 10:44But
- 10:45if you want to make it for example
- 10:4712-bit then you you want you need to
- 10:51give
- 10:52this 12 as the parameter width
- 10:54parameter.
- 10:55So, for example, in here our
- 10:58in in this call,
- 11:00I am giving the width 12 and this module
- 11:03becomes 12-bit max from now on.
- 11:07So, in here this D0 and D1 inputs must
- 11:10be 12-bits.
- 11:13There is also another construct that you
- 11:15can use type def enum.
- 11:18This type def is used to create a new
- 11:20data type. For example, until now we saw
- 11:22only one data type. It was logic and we
- 11:25saw three, but forget three. No problem
- 11:27with three. We will not use it.
- 11:29But for example, you can define a logic
- 11:32data type For example, you can define a
- 11:34data type that corresponds to 8-bit
- 11:37value. For example, this say We are In
- 11:40here, we are defining a data type uh
- 11:43type def logic
- 11:4570. It means that 8-bit value, and I
- 11:48named it as a logic 8.
- 11:51So, from now on, whenever I wrote logic
- 11:548, it means that logic 70. But, I am
- 11:58just calling it as a logic 8. For
- 12:00example, in here, I told logic 8
- 12:02example, it means that example is a
- 12:058-bit value, 8-bit signal.
- 12:08So, these are
- 12:10these two are equal.
- 12:18There is also another struct enum. Enum
- 12:21is used to create enumerated data type.
- 12:24Uh this is a little bit different.
- 12:27Uh In here, I was I was defining a data
- 12:30type, but in enum, I am saying that
- 12:35I I have
- 12:37two bit signals. For example, in here, I
- 12:40am saying that type def enum,
- 12:42and I am saying that enum type def enum
- 12:44is a keyword in here, and I am saying
- 12:46that I have a two bit two bit signal.
- 12:51And this two bit signal can take these
- 12:53values: idle, reading, writing.
- 12:56And the name of this enum type is FSMT.
- 13:02So,
- 13:04for example, in here, I defined a FSMT
- 13:07type FSM I I
- 13:11defined FSMT and
- 13:13name it as example state.
- 13:17This example state actually is a two bit
- 13:19logic value, but its value becomes idle,
- 13:22reading, or writing.
- 13:24You can, for example, assign For
- 13:26example, example state
- 13:29and assign example state to idle.
- 13:32How this
- 13:34runs?
- 13:35For example, the in here, the tool
- 13:37assigns some values to idle, reading,
- 13:39and writing. For example, it says that
- 13:41idle is 00, reading is 01, writing is
- 13:4411, for example.
- 13:46And then whenever you assign idle to
- 13:49this example state, actually it assigns
- 13:5100.
- 13:52The good thing in using enum is that
- 13:55while running simulation in the
- 13:57waveform, you can instead of reading the
- 13:59zeros ones, you can read the state. For
- 14:02example, if you define a, for example,
- 14:04finite state machines and it has
- 14:05different states, for example, it has a
- 14:07init state, it has read state, it has a
- 14:09write state. Instead of looking to do
- 14:120011 in the waveform, you can just
- 14:16directly see the state names. For
- 14:18example, read, write, idle. So, the good
- 14:20thing by using enum is
- 14:23only this one. But and it is very, by
- 14:26the way, it's very useful
- 14:28data type.
- 14:33This is This was typedef. If you want to
- 14:36just define a basic type definition by
- 14:39using logic,
- 14:40you can use typedef. Typedef enum is
- 14:43that I described. You are enumerating
- 14:45the type. Yeah, just enumerating it
- 14:47means that you are assigning a word to a
- 14:49number.
- 14:51And there is also another structure,
- 14:54typedef struct. This is very useful,
- 14:56also.
- 14:57You can use typedef struct
- 15:00to create a new struct data type. Struct
- 15:02means in here that it consists of more
- 15:04than data type. For example, in here, I
- 15:07am designing a typedef struct.
- 15:09Typedef struct package. This is a
- 15:11package data type and its name is called
- 15:15ST control, for example.
- 15:18For example, in here,
- 15:20in this data type, I have a four-bit
- 15:24mode,
- 15:25three-bit configuration, and one-bit
- 15:27enable field, for example. So, it
- 15:29consists of this data type. ST control
- 15:32consists of these three different
- 15:35values.
- 15:37And each of them has different number of
- 15:40bits, for example.
- 15:42So, how can you use it? Maybe I can give
- 15:45an example. For example, this are By the
- 15:47way, this is bit.
- 15:49Until now, I showed you logic logic 108
- 15:53and Z. If you define it as a bit, bit
- 15:56logic is same, but bit can have a value
- 15:59only one or zero,
- 16:01not X and Z.
- 16:03So, you can use bit also, but what when
- 16:06you run simulation and if you use bit,
- 16:08you can only see one or zero.
- 16:11But if you use logic in the simulation,
- 16:13you can see X and Z also at the same
- 16:17time.
- 16:18But, of course, if you use logic,
- 16:20logic
- 16:22corresponds to two-bit because it has a
- 16:24four states.
- 16:26Then, simulation runs a little bit
- 16:28slower. So, there is a slight difference
- 16:30only. But still, but using logic is
- 16:34better still.
- 16:35I can give an example to this struct
- 16:38type. For example, in here, you want to
- 16:41define
- 16:42a
- 16:44ST control data type.
- 16:46For example, I can say that my control,
- 16:49for example. I
- 16:50In a similar way,
- 16:52I am just writing the type name. This is
- 16:54a type name, type def name, and this is
- 16:57my type. And my controller
- 17:01from now on, my controller has these
- 17:04fields. It's a signal. This my control
- 17:07is a signal, and this signal has
- 17:10four-bit mode, three-bit configuration,
- 17:12and one-bit enable. And in order to
- 17:14access these values, you will to just
- 17:17write my control
- 17:19{dot} for example enable. If you want to
- 17:21enable access to enable bit. If you want
- 17:24to access the mode for example, you need
- 17:26to say my control {dot} mode.
- 17:29You can access with {dot}.
- 17:37This is type def struct. If you write
- 17:38type def struct, you are combining
- 17:40different types of data types
- 17:44and then forming a new data type.
- 17:46But there is also type def union.
- 17:49Type def the union, there is a slight
- 17:51difference between type def struct and
- 17:52type def union. In type def union,
- 17:55you are forming the different views of
- 17:57the same data.
- 17:59In here for example, this this struct
- 18:02actually
- 18:03total there is four bit in here, three
- 18:06bit in here, one bit here. This is total
- 18:08eight bit.
- 18:09But in here, I defined a data type type
- 18:13def union patch. Now, I use union.
- 18:17And this data type says that I have a
- 18:20data this data. For example, I can
- 18:23create a data by using this union type
- 18:25data type data. For example, my data.
- 18:29And this my data consists of either data
- 18:33byte view or data half view. For
- 18:35example, when you look at data byte is
- 18:3816 bit.
- 18:39Data half is 16 bit.
- 18:42But they keep the same value. It is not
- 18:44total. It is totally 16 bit.
- 18:48It's not 32 bit. In here, it was the
- 18:51combination of them. But in union, it is
- 18:54either of them.
- 18:56Either you can represent it as a
- 18:58either data byte or data half.
- 19:01But it is same. It is same 16 bit. You
- 19:04can either represent it as a 0 to 15 or
- 19:08it says that two dimensional logic
- 19:10array.
- 19:11It says that either two dimensional
- 19:13logic array from zero to seven.
- 19:18By the way,
- 19:21we saw one dimensional vectors. This is
- 19:24one dimensional vector. This is two
- 19:25dimensional vector. If you want to
- 19:27define a two dimensional vector like
- 19:29this one,
- 19:30you are saying that this is one to zero
- 19:33and each of them is
- 19:35from zero to seven. So, it is a two
- 19:38dimensional vector.
- 19:39You can define two dimensional logic
- 19:41vector in this way also.
- 19:43And everyone, you can add more
- 19:45dimensions here and you can define three
- 19:48dimensions also.
- 19:54So, in my data, for example, if you want
- 19:57to represent it as a data hub, you need
- 20:00to write my data data hub.
- 20:03If you want to represent it as a data
- 20:05byte, you need to write my data dot data
- 20:08byte.
- 20:10But, for example, if you change the, for
- 20:12example,
- 20:13fourth bit of this data hub,
- 20:16it also changed the data byte
- 20:17corresponding bit of the data byte
- 20:19because they are the same data. It's
- 20:21only representation. Union
- 20:23actually only representation changes the
- 20:25representation. While accessing by using
- 20:28data hub, you can access it as a one
- 20:30dimensional vector. While accessing
- 20:32through the data byte, you can access it
- 20:35by using two dimensional access. In
- 20:38order to do access, for example, if you
- 20:40say that my data
- 20:43data hub, for example,
- 20:46five,
- 20:47it is the same data as my data
- 20:51data byte
- 20:54first dimension, zero and five.
- 20:57It is same.
- 20:59If it is, for example, 10, my data data
- 21:01hub 10, it corresponds to my data dot
- 21:05data byte one because I need to switch
- 21:08the other row.
- 21:10And
- 21:11uh in here second element of the other
- 21:14row.
- 21:15Okay?
- 21:18Yes, one two.
- 21:21Is it clear?
- 21:24Okay.
- 21:25Now, I will give you some examples about
- 21:28the finite state machines.
- 21:30Uh
- 21:31Finite state machines are two types.
- 21:33Now, we will see how to define the
- 21:35finite state machines using the
- 21:36SystemVerilog.
- 21:37Uh finite state machines
- 21:39uh has next state logic, state register,
- 21:42and output logic. In here I have a I
- 21:45have a register. This keeps the state.
- 21:47And in order to build a finite state
- 21:49machine, always you have these three
- 21:52components: next state logic, state
- 21:54register, and output logic. This is the
- 21:56output logic. Output logic decides on
- 21:58the output. Next state logic decides on
- 22:01the next state. So, whenever I reach a
- 22:05state in order to decide on the next
- 22:07state, I need to give
- 22:09this state to my next state logic and
- 22:11inputs also. And this one
- 22:14this block generates the next state.
- 22:16But, this is combinational block.
- 22:18Whenever clock comes, we are switching
- 22:20to next state.
- 22:22And this here in here we are keeping our
- 22:25state.
- 22:29There are two types, Moore and Mealy.
- 22:32The only difference is that in Moore
- 22:34output is depends on the state. In
- 22:37Mealy, output is depends on both input
- 22:39and state at the same time. This is the
- 22:41difference. But, by the way, while
- 22:42writing a code, we don't care whether it
- 22:45is Moore and Mealy. Well, the synthesize
- 22:48tool
- 22:49uh can do what can put whatever
- 22:52it wants.
- 22:53Uh that's why I mentioned about
- 22:55abstraction. We don't care whether it is
- 22:57Moore and Mealy because it is abstracted
- 22:59to us. Uh we don't deal with them.
- 23:03So, in here I have an example of a
- 23:05finite state machine. I have a clock
- 23:07input, reset input, and Q. Reset in here
- 23:10is important because this is a good
- 23:12example. While when I started the finite
- 23:15state machine, I need to start with a
- 23:17known state. For this reason, I have to
- 23:20use reset, for example.
- 23:21For this reason in here, I have to use
- 23:23reset
- 23:25to initialize the registers.
- 23:29In here, I have module module as clock,
- 23:32reset, input, and Q output. This module
- 23:34has no
- 23:35has no input, by the way. It has a
- 23:39output, just output.
- 23:41And what it does, it has three state,
- 23:44and I defined the state as enum.
- 23:48So, type def enum logic, it says that
- 23:50two-bit value. I have a two-bit
- 23:52enumerated values, and they are S0, S1,
- 23:56and S2. You can put S3, by the way, but
- 24:00we are not using S3, for this reason we
- 24:01do not put. Most likely, S3 corresponds
- 24:03to zero, S1 corresponds to, for example,
- 24:0501, S2 corresponds to 10, and there is
- 24:09no state corresponding to 11.
- 24:12This is two-bit. Two-bit represents four
- 24:14value, but we are only using three-bit.
- 24:18Still, we keep we need to use two-bit to
- 24:19keep it, but we we we have three-bit in
- 24:23here.
- 24:24And
- 24:26by using this enumerated state type, I
- 24:29am defining two variables, two signals.
- 24:31One of them is state, and other one is
- 24:33the next state.
- 24:35So, most likely, this is the next state.
- 24:38Whenever clock comes, I have I will
- 24:41assign this next state to state.
- 24:44In here, I have a flip-flop.
- 24:47This flip-flop has a asynchronous reset,
- 24:50and positive edge flip-flop. Whenever
- 24:53reset comes, I am initializing the state
- 24:55to S0.
- 24:57But otherwise, if there is no reset,
- 25:01I am always assigning next state to
- 25:03state as I draw here.
- 25:06And this is the next state logic.
- 25:08By the way, for the flip-flop, in order
- 25:11to use form flip-flop, I use always FF
- 25:14statement.
- 25:16In here, in order to define on the next
- 25:18state logic,
- 25:20I am using always comb block
- 25:23because this is combinational.
- 25:25And in this combinational logic, I am
- 25:28saying that, by the way, this finite
- 25:30state machine just it has an input, for
- 25:33example, clock input.
- 25:36And whenever, for example, this clock
- 25:38comes three times,
- 25:41and in the, for example, in here, when
- 25:44it comes third time, it gives one.
- 25:48It gives a one value. It is divide by
- 25:50three. So, clock comes
- 25:55and
- 25:56at each at every
- 25:59third occurrence of the clock, it gives
- 26:01a logic one.
- 26:03Okay, what what this FSM is doing.
- 26:06So, when I look at the next state logic,
- 26:10every time
- 26:12when when I was in a state, I am
- 26:14switching to the next state. For
- 26:16example, while I was in S0 state, I am
- 26:19switching to the S1 state. If I am in S1
- 26:22state, I am switching to S2 S2 state.
- 26:25Which as in S2, I am switching to S0
- 26:27state.
- 26:28And in default, I put a default value in
- 26:30here not to create a latch
- 26:34mistakenly
- 26:36for
- 26:37This is my default value.
- 26:40In the default one, the next state is
- 26:42S0. And output logic, this is also a
- 26:45combinational logic. You can build the
- 26:47combinational logic by using always
- 26:49comb. But in here,
- 26:50in the example, we put we use a size
- 26:53statement. In this assignment statement
- 26:55it says that
- 26:57if state is zero S0, it is equality
- 27:00comparison. If state if if state is S0,
- 27:04this gives one.
- 27:06So, state equal equal means that
- 27:08comparison. If state is equal to S0, I
- 27:11am assigning
- 27:13uh
- 27:14one to Q.
- 27:17So, whenever state becomes, for example,
- 27:19in here it is first
- 27:21uh
- 27:23Yeah, in for example, assume that it is
- 27:25in here, state is S1.
- 27:28It is S2 S2 and immediately it goes to
- 27:32S0. Whenever it becomes state becomes
- 27:34S0, during that time Q becomes Q gives
- 27:37the value of one.
- 27:40And this is the corresponding
- 27:42uh system Verilog code. Is it clear?
- 27:45Do you have any question?
- 27:50Uh this is also another example.
- 27:53Uh in here I am doing a sequence
- 27:55detection.
- 28:01So,
- 28:02for example, which sequence I am
- 28:04detecting in here?
- 28:05Uh
- 28:07For example,
- 28:10yeah, this is the FSM state diagram.
- 28:13Most likely you are familiar with this
- 28:15diagrams from your logic design course.
- 28:19Uh so, in the I said I'm starting with
- 28:21S0 state and in S0 I am giving the
- 28:24output as zero. Whenever one comes, I am
- 28:27staying in S0, but whenever
- 28:30zero comes, I am switching to S1 state.
- 28:33But in S1 state I am still giving the
- 28:36output as zero.
- 28:37In S1 state, while zero comes, I am
- 28:40staying in this state and whenever one
- 28:42comes, I am switching to S2 state and in
- 28:45S2 state I am giving an output one.
- 28:49And while in S2 state, if zero comes, I
- 28:53am switching back to S1 state. If one
- 28:55comes, I am switching to S0 state.
- 28:57So, basically, actually, this one just
- 28:59detects
- 29:01For example, when you look at here, it
- 29:03detects
- 29:04for example, zero
- 29:07one.
- 29:08Right? If uh when I started from here,
- 29:11if zero comes and then after one comes,
- 29:14if I detect zero one, it gives one.
- 29:17So, that's why when another zero comes
- 29:20here, it goes back to S1 state and waits
- 29:23for another one to to give one. So,
- 29:26whenever in this one, if another zero
- 29:29comes, it goes to S1 state and waits for
- 29:31another one. So,
- 29:33it switches back to S2 state and gives
- 29:35the one as output.
- 29:37And this is the corresponding Verilog
- 29:39code. Still, I am using a type def enum
- 29:41logic in here to to to show the states
- 29:45state types. And I have two state types,
- 29:47one of them current one and other one is
- 29:49the next one. This is my flip flop.
- 29:51This is just two flip two two-bit flip
- 29:54flop because it keeps states.
- 29:56And
- 29:58this is my next state logic always comb
- 30:01block.
- 30:02Uh now,
- 30:03I am not just changing the state because
- 30:06input is also important. I have an input
- 30:08in here. My input is A.
- 30:10And
- 30:12if, for example, A in S0 state, if A is
- 30:16one, I am keep staying in S0 state.
- 30:20Uh but, if it is zero, I am switching to
- 30:24S1 state. So, in the next state logic,
- 30:27now,
- 30:28the input also matters for this reason.
- 30:31Uh I am also uh
- 30:34using if-else statements to decide on
- 30:36the next state. This one uh decides on
- 30:40the next state.
- 30:42And also in here, I have also
- 30:46the assignment. And in this assignment
- 30:49uh I am deciding on the output logic.
- 30:51And this output logic the output is
- 30:54smile. The smile is becoming one
- 30:56whenever my state is is S S2.
- 31:00Okay? Is
- 31:02Is there anything
- 31:04you didn't understand in this Verilog
- 31:06code?
- 31:13This is the Mealy version of it. In
- 31:16Mealy version, the difference is that in
- 31:18here I mentioned in Mealy version
- 31:21uh the output in here the output was
- 31:24depending on the only state. In Mealy
- 31:26one, it was also depending on the input.
- 31:29So, in the Mealy version
- 31:32while
- 31:34actually deciding on the next state, at
- 31:36the same time I am also deciding on the
- 31:40output logic. So, while
- 31:42I am looking to state and both state and
- 31:45inputs also
- 31:47uh
- 31:48gives the smile
- 31:50uh output also.
- 31:53So, in here this is the same.
- 31:56The state register deciding is same.
- 31:58Always I am switching to the next state.
- 32:01And in here in always comp block, now I
- 32:04will decide on the next state and output
- 32:06logic.
- 32:07So,
- 32:08in here first I I am initializing the
- 32:12smile as zero.
- 32:15And for example, if state is S0 and uh A
- 32:20is one, then I am staying in this S0.
- 32:24Because this is Mealy by the way.
- 32:26So,
- 32:27this representation FSM representation
- 32:30is a little bit different because more
- 32:33depends on only state output in more
- 32:35depends on only output.
- 32:37But in Mealy, it depends on state and
- 32:40input also at the same time. For this
- 32:42reason,
- 32:43>> [clears throat]
- 32:44>> in here, in this state diagram,
- 32:47I am mentioning about the input, but
- 32:49also I am giving the output,
- 32:51corresponding output. So, in here, this
- 32:53output depends on this input and also
- 32:55state it is on.
- 32:57It is in.
- 32:59So, in here, if state is S0 and if A is
- 33:031, my next state is S0.
- 33:06Otherwise, my next state is S1.
- 33:09When you look at for the S1 state case,
- 33:13whenever
- 33:14in S1 state, if
- 33:17input 1 comes, I am giving the output as
- 33:201. For this reason, in S1 state, if A is
- 33:231, then I am saying that smile needs to
- 33:26be 1.
- 33:27Otherwise, this is the default value.
- 33:30Smile is always in other cases, smile is
- 33:330, but only while running this code,
- 33:36this is blocking statement, by the way.
- 33:38This is
- 33:39First, I am running this one.
- 33:41And after
- 33:43running the others,
- 33:45if I do another assignment, smile is
- 33:48replaced with the new assignment,
- 33:50because this is the blocking assignment.
- 33:59So, only in this condition, in
- 34:03S1 state, and if input is 1,
- 34:07I am
- 34:09giving the output as 1, smile output as
- 34:121. In other cases, I am going switching
- 34:15to the next state and smile is always
- 34:17kept as 0.
- 34:20You can later, after the course, you can
- 34:23later also inspect the examples.
- 34:27So, I can we can do some more examples.
- 34:29In In I have an
- 34:31arithmetic logic unit and operations
- 34:32example. For example, while you are
- 34:34defining a
- 34:35uh uh
- 34:36processor, you will use these examples.
- 34:39You will write such codes, for example.
- 34:41In here, I have a basic ALU module. And
- 34:44this ALU module takes M-bit inputs for
- 34:47A, B, and it it takes
- 34:50A and B are the inputs. Most likely, we
- 34:52will do addition, subtraction, and
- 34:55operations on these inputs depending on
- 34:57the ALU control signal. ALU control is a
- 34:592-bit signal.
- 35:00And I am giving the M-bit result as a
- 35:03result.
- 35:05And this module does behaves as if ALU
- 35:08control is 0 0, I am doing the add
- 35:10function. If it is 0 1, I am doing
- 35:12subtraction. If it is 1 0, I am doing
- 35:14and and so on.
- 35:17So, depending this ALU control, I am
- 35:18doing some operation on these A and B
- 35:21inputs. So, for example, this table says
- 35:24that if it is 0 0, I need to do and. So,
- 35:27this is just In here, there is nothing
- 35:29sequential. It is a combination logic.
- 35:32And I am writing always come begin
- 35:34case ALU control. And depending ALU ALU
- 35:37control signal, I am doing to I am
- 35:39writing the corresponding operation. For
- 35:41example, in here, if ALU control is 0 0,
- 35:44it is going to this 0 0 case statement,
- 35:46and the result is becoming A plus B.
- 35:49And these are the other ones. I am
- 35:51writing still in I am I am defining the
- 35:54default statement because
- 35:56I want I don't want to infer latch for
- 35:59the result. This is why I use default
- 36:01statement in here as I told before.
- 36:06So, and if you synthesize it, this is
- 36:08the logical correspondence of this
- 36:10circuit.
- 36:11But this is the this is abstraction for
- 36:14us. We don't deal In this course,
- 36:16actually, I showed you some logic uh
- 36:18fundamentals, but we will not deal with
- 36:20the logic, also.
- 36:24The more examples, for example,
- 36:26shifters, logical shifters,
- 36:28uh arithmetic shifters. There is a small
- 36:30difference, slight difference between
- 36:32them. Logical shifter shifts the value
- 36:33to left or right and fills the empty
- 36:36spaces with zeros. And arithmetic
- 36:38shifters same as logical shifter, but on
- 36:41the right shift you you are filling the
- 36:44empty space with the old most
- 36:46significant bit.
- 36:47This is important because in arithmetic
- 36:50shift you need to you want to keep the
- 36:52sign of the number.
- 36:55For example,
- 36:57people use arithmetic shifter, for
- 36:59example, divide the negative number. For
- 37:01example, while dividing a minus eight,
- 37:03for example, you want to divide minus
- 37:05eight by half and the result is minus
- 37:07four.
- 37:09If you do
- 37:11logical shifter, you you don't you
- 37:13cannot get minus
- 37:16minus four. You are getting four.
- 37:19But if you use arithmetic shifter, in
- 37:21this way you are getting minus four.
- 37:25>> [clears throat]
- 37:25>> Logical shifter always fills it with
- 37:27zero, left or right. In here, you are
- 37:32you in here I have a value and in here I
- 37:35am saying that how much bits needs to be
- 37:37shifted. For example, this says that
- 37:3911001 number is shifted
- 37:43right by two.
- 37:45So, it shifts two.
- 37:50These are the shifters. RISC-V is using
- 37:53all these shifter types in
- 37:55in their operation types. There are
- 37:58shifters, shift operations in RISC-V.
- 38:01Counters increments on each clock edge.
- 38:05So,
- 38:06>> [clears throat]
- 38:07>> you can use just a adder, for example,
- 38:10and add one at every time and build a
- 38:13counter.
- 38:14So, counters are used digital clock
- 38:16displays and for program counters. We
- 38:18will see program counters. For example,
- 38:19we We
- 38:20in while defining a risk 5 processor, we
- 38:23will use program counters. Uh so, for
- 38:26example, you can use program counter to
- 38:28keep track of the current instruction
- 38:30executing, but we will show it later.
- 38:33So, counters, it's just a flip-flop, but
- 38:37it is counting.
- 38:39Uh but its implementation is of course
- 38:41if you are incrementing it by one by one
- 38:44by one,
- 38:45then you have a one-bit adder in here
- 38:47also.
- 38:49So, this is a counter implementation.
- 38:52At each clock, if reset comes, counter
- 38:54starts with zero because you have to
- 38:56start with a known value.
- 38:58And otherwise,
- 39:00at every time you are increasing Q to
- 39:02one one one by
- 39:04So, this is a basic counter
- 39:06implementation.
- 39:09Uh every time you are adding one to Q
- 39:11and assigning it to it. But this is the
- 39:13alternative version.
- 39:15Uh
- 39:16in here,
- 39:17I have a
- 39:19Q output, but also I have a next Q
- 39:21value.
- 39:22And I am assigning next Q always as Q
- 39:25plus one, and whenever clock comes, I am
- 39:28assigning next Q to Q.
- 39:31Uh this is more verbose one, but
- 39:34generally we use these versions while
- 39:36coding
- 39:37processors.
- 39:39Always we are always separating the
- 39:41combinational and logic blocks.
- 39:43And in here, instead of assign
- 39:45statements, we are using always comp.
- 39:48Generally, this is our coding style, for
- 39:50example, in in Tubitak, this is our
- 39:52coding style.
- 39:54So, we are using this version actually
- 39:56because it is
- 39:57uh if you are doing more complex logic,
- 40:00this always FF block becomes more
- 40:02complex. So, instead of it making a very
- 40:06complex of FF always FF, it is better to
- 40:09separate it into always comp and always
- 40:12FF blocks.
- 40:14So, this is the shift register
- 40:16implementation example.
- 40:18So, if load is one, for example, you are
- 40:22writing a value to M bit register. And
- 40:25when load is zero, it is at each clock
- 40:29edge, it is shifting
- 40:31one bit to to right.
- 40:36Yeah, so it is a like serial to parallel
- 40:38converter. First, you are loading the
- 40:40value as parallel. For example, if you
- 40:42have a 8-bit register, you are loading
- 40:44the 8-bit value.
- 40:46And after this load operation,
- 40:48at every time you are shifting it one
- 40:50bit right and giving the shifted one,
- 40:53the
- 40:54right most one to the output.
- 40:57And this is the corresponding system
- 40:59Verilog code for this shift register.
- 41:11So, in here maybe we can give a break
- 41:14because
- 41:15we we finished at 30, right? In the
- 41:18previous one.
- 41:19Open it's more than 1 hour we started.
- 41:22Okay, we can give a break.
- 41:25And we can start again at 45.
- 41:3214:45
- 42:39>> We will go back.
- 42:50So, now we will see the system Verilog
- 42:52memory types.
- 42:55Memory types are used to define the
- 42:56memory. Normally, memory means actually
- 42:59flip-flop latches. They are memories.
- 43:01But, if you want to build many of them,
- 43:03for example, a memory 2 megabyte for
- 43:05example, if you want to build a 2
- 43:06megabyte memory, you have to define
- 43:09multi-dimensional
- 43:11logic gates, logics, actually logic
- 43:13structures.
- 43:14You need to use multi-dimensional
- 43:16logics.
- 43:18And
- 43:19it's yeah, memory is used efficiently to
- 43:21store large amounts of data. And, for
- 43:23example, you can define the data value
- 43:25read width, for example, M bit.
- 43:28And at each time you can read M bit
- 43:31value and write M bit value, for
- 43:33example. And you can keep it in M bit
- 43:36address, for example. If you are keeping
- 43:38M bit value at M bit address, it means
- 43:42that
- 43:43you are keeping M times 2 to the N.
- 43:47You have M times 2 to the N bit.
- 43:51Because this is the address.
- 43:52So, you are defining you are giving an
- 43:54address, for example, if you define five
- 43:56if you are giving five bit address, it
- 43:58means that you are
- 44:00addressing between 0 to 31.
- 44:02So, and if you each if each address
- 44:05keeps 32 bit value, 32 value. Then total
- 44:09size is becoming
- 44:112 to the 5 * 32
- 44:13bits
- 44:14or 2 to the 2 to the 5 * 4
- 44:18byte, for example.
- 44:21So,
- 44:22if you want to store a data in
- 44:25uh in uh
- 44:27chip, in an integrated circuit, there
- 44:30are three different values three
- 44:32different types. One of them is DRAM,
- 44:35dynamic random memory access memory. Uh
- 44:38DRAM consists of a transistor and
- 44:40capacitor. This capacitor keeps the
- 44:41value. And if you want to access the
- 44:44value stored in this capacitor,
- 44:47yeah, this is not like
- 44:48cross-coupled inverter. This is just a
- 44:50capacitor and capacitor keeps the value.
- 44:52For example, if you load a voltage to a
- 44:54capacitor, and then keep this value in
- 44:57this capacitor, then it is a storage.
- 44:59It's like a storage. Uh but, if you want
- 45:02to read it, you need to just apply to
- 45:04one to this word line and read it from
- 45:06the bit line. This is
- 45:08basic DRAM memory.
- 45:11Uh
- 45:12Another one is a static asset memory.
- 45:14This is the one we we saw. This is
- 45:17cross-coupled inverter.
- 45:19It has a bit line and cross bit line and
- 45:22not of them. And if you want if you want
- 45:24to access it, you need to just trigger
- 45:26this word line and then get read the
- 45:28data.
- 45:30And other type is the read-only memory.
- 45:32Read-only memory means that
- 45:35just, for example,
- 45:37you have a wire and you are just
- 45:39connecting into the VDD or VSS.
- 45:42Then it is a read-only memory because
- 45:45if you connect a wire to one to be, for
- 45:48example, VDD, then if you read a if you
- 45:50read this wire, you are always getting
- 45:53one.
- 45:54This is read-only memory. You cannot
- 45:56change it. In read-only memory, you
- 45:57cannot change it.
- 45:59And in all by using all these
- 46:02structures, you are defining
- 46:04two-dimensional
- 46:05data
- 46:06and these two-dimensional data forms the
- 46:09memory.
- 46:10So, in here at the beginning I mentioned
- 46:12that M-bit data value and M-bit address.
- 46:15So, M * 2 to the N value you can build a
- 46:19memory.
- 46:20And the memory capacity is so. In order
- 46:23to access the memory, we need to use
- 46:25decoder. For example, if address is
- 46:262-bit,
- 46:28I can access 0 0, 1,
- 46:302, or third rows. So, you have to use
- 46:34you need if you get a 2-bit address,
- 46:36then you need to select the
- 46:38corresponding word line
- 46:40to access and this word line can be
- 46:43either this one, this one, this one,
- 46:44this one. So, this 2-bit address needs
- 46:47to be converted to two 4-bit signal.
- 46:51So, for example, if you want to access
- 46:54in here, if you want to access uh
- 46:57row
- 46:58three,
- 46:59then you are giving address 1 1 and this
- 47:021 1 activates this
- 47:04word line
- 47:05and you can read
- 47:07the values stored in here.
- 47:10By the way, this when you look at here,
- 47:13in here, there is 2-bit address
- 47:16and each address keeps a 3-bit value.
- 47:19So, in here there is a 2 to 2 * 3-bit
- 47:22data. So, total in here there is 12-bit
- 47:26data. You you can count it.
- 47:29These are the memories uh and we will
- 47:31see how to define the memory arrays in
- 47:34SystemVerilog. Uh of course, in memory,
- 47:36we are using two-dimensional memories
- 47:39and each bit cell stores 1 bit.
- 47:42Uh I mentioned about the com-
- 47:44yeah, the array size. Uh depth means the
- 47:47number of rows and width means the
- 47:49number of columns. So,
- 47:51this is the width.
- 47:53This is the depth.
- 47:55And if you want, for example, if you
- 47:57want to access 32-bit data, your width
- 47:59can be 32. For example, if you want to
- 48:02keep 124
- 48:05uh
- 48:06words, then your depth is 124, for
- 48:09example.
- 48:11So,
- 48:12uh
- 48:13this is, for example, in here, if you
- 48:16have a such a memory, then your address
- 48:18is 10 bits, and your
- 48:21data in here, you are storing 4 byte.
- 48:26So, uh this this one corresponds to
- 48:28here, yes.
- 48:30So, how can we define a single port RAM
- 48:32in SystemVerilog?
- 48:34In here, I have clock and write enable
- 48:37input.
- 48:38Uh this is my clock. This is write
- 48:40enable. If I want to write, I am just
- 48:43triggering this input.
- 48:44I have a A input, 8-bit, and uh
- 48:48data
- 48:50write destination and read destination
- 48:52inputs.
- 48:54And whenever I want to write, I need to
- 48:57make the write enable one.
- 48:59And this is the description.
- 49:01First, I need to create the memory
- 49:03itself. So, what is memory? Memory is a
- 49:05two two-dimensional signal.
- 49:08Normally, I was defining here, for
- 49:09example, logic
- 49:117 to 0, for example,
- 49:14and it was creating a vector, right?
- 49:16One-dimensional vector. But memory is
- 49:18two-dimensional vector. So, in order to
- 49:20define two-dimensional vector, I am
- 49:22using two-dimensional logic structures.
- 49:24And this says that
- 49:26I am using
- 49:28in each row, there are three bits, but
- 49:30there are 256
- 49:33rows.
- 49:35And this is my RAM.
- 49:38This is memory, memory itself.
- 49:41And
- 49:42this is the address input. By the way,
- 49:44this is not data. This is address input,
- 49:47and this is the data inputs. I I I told
- 49:50it wrongly.
- 49:51Address is
- 49:528 bits because 256
- 49:55is addressed by 8-bits. 256 location
- 49:59addressed by 8-bits.
- 50:01So, whenever
- 50:04for the output
- 50:06if
- 50:07whatever A addresses, I am giving the
- 50:11corresponding 3-bit 3-bit to RD. I am
- 50:14assigning it to RD. So, for example, if
- 50:16A is zero
- 50:18this first element of RAM RAM 3-bit
- 50:22of it assigned to RD. Okay? So, this is
- 50:25like combinational read because I'm
- 50:27doing combinational read in here, not
- 50:29doing sequential read.
- 50:31Read is combinational
- 50:33but raw write is always must be
- 50:35sequential. So, in write, whenever clock
- 50:38comes, if write enable signal is one, I
- 50:42am just assigning this VD to
- 50:44corresponding RAM
- 50:46uh row. So, this VD signal is 3-bit
- 50:49signal. I'm assigning to the RAM.
- 50:52That's all.
- 50:54Is it clear?
- 50:58So, you can also define multi-port
- 50:59memory. Uh for example, in here, I
- 51:02define two read ports and one write
- 51:04ports. Two read ports has two address,
- 51:06A1 and A2, and two data outputs, RD1 and
- 51:09RD2, and one write port, A3, write data
- 51:13three, and write enable three.
- 51:15Because
- 51:16I am not writing always. In each cycle,
- 51:18you can read it because read is not
- 51:20destructive. You can read the memory, no
- 51:23problem. But, if you want to write it,
- 51:25you want you need to write it only if
- 51:27you want to write. Otherwise, you
- 51:29shouldn't write.
- 51:30Uh so, for this design, write is depends
- 51:32on enable signal also. Write has enable
- 51:34signal. And this is the corresponding,
- 51:36for example, 32 * 32 register file with
- 51:39two read and write one write port. By
- 51:41the way, while designing a RISC-V
- 51:43you will exactly use this register file,
- 51:46for example.
- 51:47In here, I have two read ports,
- 51:49uh one write port,
- 51:51and read is combinational.
- 51:54In here, I am doing combinational read.
- 51:56Uh so,
- 51:58for example, in here, there is a special
- 52:00case. If read address is zero, I am
- 52:03giving zero to output. This is a special
- 52:05case. You will see it after 4 weeks why
- 52:08I
- 52:09this this example coded in a such way.
- 52:12Uh but, otherwise, you are giving the
- 52:14corresponding data to output. RD1 and
- 52:17RD2 output. What about write section? In
- 52:20write section, whenever clock comes, if
- 52:23write enable enabled,
- 52:25then you are writing this VD3 to this
- 52:27flip-flop, but corresponding row of the
- 52:29flip-flop. Okay?
- 52:34Is this example clear?
- 52:37You can also inspect them in ROM.
- 52:39Uh
- 52:40what about ROM? ROM has no write input.
- 52:44So, I have an address input and getting
- 52:47the output.
- 52:48So, whenever I provide an address, I'm
- 52:50getting the corresponding output in this
- 52:52row, in the row that corresponds this
- 52:54address.
- 52:55And ROM, if you want to build a ROM in
- 52:58your uh for your chip, uh you need to
- 53:02just
- 53:03create a read port,
- 53:05and at the beginning, you need to give
- 53:07data to this ROM.
- 53:10And you can give this data from a file.
- 53:12This is a file, memfile.dat file.
- 53:15And this .dat file has values actually
- 53:18in here.
- 53:20Uh
- 53:20has some data.
- 53:22Uh this ROM actually has 128 rows, and
- 53:26each row has 32-bit data.
- 53:31And
- 53:33at the beginning,
- 53:34by using this read mem
- 53:36H,
- 53:38I am reading a hexadecimal
- 53:41data from this file, and this file in
- 53:44this file there are 128 entries for
- 53:46example and these entries are loaded to
- 53:49the ROM.
- 53:50So, instead of writing actually assign
- 53:53for example assign
- 53:55ROM
- 53:570 is
- 53:59uh 0 1 2 3 4 5 6 for example in this way
- 54:03and if you if instead of writing 128
- 54:07assign statements to define the initial
- 54:09values of the ROM we are just
- 54:12putting a file data we are putting the
- 54:15data in a file and then reading this
- 54:17file and then
- 54:18loading this
- 54:20data to ROM this ROM signal.
- 54:23And after that this is by the way
- 54:24initial statement initial statement runs
- 54:26once while seeing the simulation I will
- 54:29show this statements in detail. Uh
- 54:32this
- 54:34I will show in detail this statement but
- 54:36while running the simulation this
- 54:38statement runs only once at the
- 54:40beginning and never runs again.
- 54:43And this is the read corresponding read
- 54:45port. Read port always assigns the
- 54:48corresponding address to the output.
- 54:52System Verilog has a concept of delay.
- 54:54Uh delay
- 54:56is described by dash and
- 54:59delay amount.
- 55:00For example in here I have a module
- 55:02example module it has some inputs and
- 55:05doing some operations.
- 55:07And these are the structural description
- 55:09of these operations and these delays
- 55:12says that
- 55:15for example this statement is evaluated
- 55:18but assigned to these values after one
- 55:21delay
- 55:22after one unit time.
- 55:24In here
- 55:26this statement is evaluated but assigned
- 55:28to N1 after two unit delay time.
- 55:31And two unit delay time two unit delay
- 55:33time four unit delay time.
- 55:37It's just delaying the assignment. So,
- 55:39if there was no
- 55:42one here, this would be assigned
- 55:45immediately. This statement would be
- 55:47assigned immediately. But, since there
- 55:49is a delay statement here, the
- 55:51assignment is delayed one unit time.
- 55:53This unit depends nanosecond,
- 55:55picosecond, uh microsecond. You are
- 55:58defining it.
- 55:59Uh but, this is unit time.
- 56:02Uh but, this is only for simulation.
- 56:05For example, if you write such a
- 56:06statement and say that while
- 56:09uh
- 56:10synthesizing this system Verilog code
- 56:13and build a actual hardware, it will not
- 56:16put any delay. This is only for
- 56:18simulation, not for actual hardware.
- 56:21Because, we don't know how to control
- 56:22the delay value in actual hardware. So,
- 56:25this is not realistic thing. This is
- 56:27only for simulation. And, you will see
- 56:29it is very useful in simulation,
- 56:32especially in order to generate a clock.
- 56:36So, they are not corresponding to the
- 56:37delay of actual hardware. And, here here
- 56:40you can in here you can see the
- 56:43uh
- 56:43simulation result. And, according to the
- 56:46simulation results, these for example,
- 56:48ABC changes its values.
- 56:50But, these statements, for example, N1,
- 56:53N2, and N3, when you look at it here,
- 56:57it is actually changed after this
- 57:00specified amount of delay time.
- 57:07Okay?
- 57:14So, in here there is an example, for
- 57:16example. In here you need to be careful.
- 57:19For example, this is not sequential.
- 57:22So, for example, you cannot say that,
- 57:24for example,
- 57:26this assignment is will be done after
- 57:28one delay time, and this assignment will
- 57:31be done after
- 57:33two delay time, but they they are
- 57:34running at the same time. For this
- 57:36reason, uh this is not after three unit
- 57:39time. This is after two unit time.
- 57:41Because every line works as parallel in
- 57:44SystemVerilog.
- 57:46So, this is the corresponding
- 57:49waveform diagrams.
- 57:53I will mention about test benches. This
- 57:55delay is useful for test benches.
- 57:57Uh test benches are the SystemVerilog
- 58:00structures. Still, they are
- 58:02SystemVerilog
- 58:03uh
- 58:04they are
- 58:06SystemVerilog modules, but they we are
- 58:08using these test benches to test, not
- 58:10not for synthesizers. You know, we are
- 58:12not using it to create actual hardware.
- 58:15So, its purpose is to test another
- 58:18module.
- 58:19And the module
- 58:22tested is named as device under test,
- 58:24and they are not synthesizable.
- 58:27Uh there are three types of it: simple,
- 58:29self-checking, and self-checking with
- 58:31test vectors. There are more complex
- 58:32ones, but you can see them maybe later
- 58:36in the different uh in the professional
- 58:38work.
- 58:40Uh so, in here, for example, I am in a
- 58:44DUT example.
- 58:45I am doing a
- 58:48I have BC ABAB C signals, and I am doing
- 58:51AND operation and then adding them.
- 58:54This is a basic function.
- 58:57Uh this is named as silly function. It
- 58:59has a AB C input and output Y, and I am
- 59:01doing this operation.
- 59:03In here, at means OR.
- 59:05The same thing, actually.
- 59:08Uh so,
- 59:10and
- 59:11assume that I described that it in you
- 59:14by writing a hardware description
- 59:16language, SystemVerilog, and I would
- 59:19like to test it. How can do it?
- 59:22I am writing a
- 59:24another module, and this module is named
- 59:26as test bench. And this test bench
- 59:29module
- 59:30calls this
- 59:32silly function, my function to be
- 59:33tested.
- 59:35And in this test bench
- 59:37I am
- 59:39applying some inputs to this function
- 59:41and
- 59:42probing its output.
- 59:44And in this test bench
- 59:46I have a initial block. This is another
- 59:49block, by the way. We Until now we saw
- 59:51always always FF
- 59:54always latch, always comp. And this is
- 59:56initial is another block. It initial,
- 59:58but this is initial is only used for in
- 1:00:01test bench.
- 1:00:03And in this test bench we are saying
- 1:00:05that we begin
- 1:00:07and at the beginning A is 0, B is 0, C
- 1:00:10is 0. And after 10 unit time, -10 means
- 1:00:1310 unit time. After 10 unit time
- 1:00:16Okay, at the beginning we are assigning
- 1:00:18ABC as 0 and waiting for 10 unit time.
- 1:00:22And after that we continue.
- 1:00:25We are assigning C to 1
- 1:00:27and waiting 10 unit time more.
- 1:00:30We are going in this way.
- 1:00:31We are assigning B to 1. At that in here
- 1:00:35B to 1, C to 0. And then waiting another
- 1:00:3710 unit time and applying these test
- 1:00:39vectors. So you see, I am applying
- 1:00:44inputs
- 1:00:45to this to this function
- 1:00:48to the another module that I want to
- 1:00:50test.
- 1:00:51And at every time I am changing the
- 1:00:53inputs.
- 1:00:56And after running this test bench,
- 1:00:58actually I will see the test bench. For
- 1:01:00example, at every time I will check the
- 1:01:02Y, for example. You will see a waveform.
- 1:01:05Uh I will upload a video uh
- 1:01:08that shows how to run Verilator. So you
- 1:01:11will see it
- 1:01:12uh in action to you.
- 1:01:14Uh but now I am using Windows. It is
- 1:01:16very hard to use uh Verilator in
- 1:01:18Windows. Uh By the way, you can install
- 1:01:19Verilator in Windows, but it is a little
- 1:01:22bit cumbersome, so for this reason I am
- 1:01:24not showing it. Uh but when you use
- 1:01:28these two
- 1:01:30modules and then run it on simulator,
- 1:01:33for example, you can see the waveforms
- 1:01:35and you can check the waveforms whether
- 1:01:37Y is
- 1:01:38correct or not. Because in here I'm
- 1:01:41applying the inputs and in here I need
- 1:01:43to check the Y visually by looking to
- 1:01:46the waveform and check that whether it
- 1:01:48is correct or not.
- 1:01:52This is the simple test bench, but in
- 1:01:54simple test bench we need to check it by
- 1:01:56eye. We need to check it by looking to
- 1:01:59the waveform.
- 1:02:01In here there is also another version of
- 1:02:02test bench. This is the self-checking
- 1:02:04test bench.
- 1:02:05The same logic. I have a test bench
- 1:02:08here, but this is self-checking test
- 1:02:10bench.
- 1:02:11And
- 1:02:12I initially in initiate my
- 1:02:15design under test in here. This is silly
- 1:02:17function that I defined.
- 1:02:20And in here I am applying the test
- 1:02:22inputs. At the beginning I am applying 0
- 1:02:240 and 0.
- 1:02:26And after 10 unit time, I am checking
- 1:02:30whether Y is 1 or not.
- 1:02:32I am doing the test in this way.
- 1:02:35This works as sequential because in here
- 1:02:37there are time unit weights.
- 1:02:40So if
- 1:02:41I don't get 0 0 0, yeah, sorry, if I
- 1:02:45don't get 1, then I am saying that the
- 1:02:47test is failed.
- 1:02:49So and after, for example,
- 1:02:52checking the first input, I am changing
- 1:02:55the C as 1 and waiting 10 unit time and
- 1:02:58checking whether Y is 0 or not. If it is
- 1:03:00not, then we are failed.
- 1:03:02And this goes in this way and
- 1:03:05in the with different inputs I am
- 1:03:07checking every time whether Y is set the
- 1:03:10correct value.
- 1:03:16Another one is that there are three
- 1:03:18methods. One of them simple, second one
- 1:03:20is self-checking, and other one is
- 1:03:21self-checking with test vectors. Test
- 1:03:23vectors is similar, but in here you are
- 1:03:26defining a example file.
- 1:03:30And this example file has the input
- 1:03:34combinations, ABC values, and expected Y
- 1:03:37value this file.
- 1:03:40And
- 1:03:43of course in here
- 1:03:45for the for the timing you are
- 1:03:47generating a clock. I will show. You are
- 1:03:49generating a clock.
- 1:03:50And
- 1:03:51at each time
- 1:03:53when clock comes
- 1:03:55you are for example reading you are
- 1:03:57giving the ABC a line
- 1:04:00and then checking whether Y is the
- 1:04:03expected value or not. But you are doing
- 1:04:05it with a clock with clock edge for
- 1:04:07example because you need to synchronize
- 1:04:09it while testing. You have a you need to
- 1:04:12have a concept of time.
- 1:04:14So you are generating a clock for
- 1:04:16assigning inputs and reading outputs
- 1:04:18because at each clock you need to switch
- 1:04:20to next line.
- 1:04:22You don't have to write clock, but it's
- 1:04:25better.
- 1:04:26Uh you can just for example in a for
- 1:04:27loop you can just write a dash 10.
- 1:04:31For example, 10 unit delay and then do
- 1:04:33it
- 1:04:34in a same way, but no no problem. We
- 1:04:37will see how to generate the clocks
- 1:04:38also.
- 1:04:40And in this stage way test bench you are
- 1:04:41generating clock for assigning the
- 1:04:43inputs and reading outputs. Uh you are
- 1:04:46reading the test work test vectors file
- 1:04:48into an array and at each time at each
- 1:04:52clock input you are assigning inputs and
- 1:04:54checking the expected outputs and
- 1:04:56compare it. This is the method for
- 1:04:59self-checking test bench.
- 1:05:01Uh so [clears throat] in here for
- 1:05:03example
- 1:05:04if you want to do it with a clock
- 1:05:07uh assign inputs for example. We will
- 1:05:09generate a clock. We will see it.
- 1:05:11And
- 1:05:12in the rising edge of the clock, we need
- 1:05:14to assign the inputs and in the falling
- 1:05:16edge of the clock, we will compare the
- 1:05:18outputs
- 1:05:19whether it is expected or not. And in
- 1:05:21the next rising edge, we will assign the
- 1:05:23new inputs and in the next falling edge,
- 1:05:26we will compare it and it will go so
- 1:05:28until we reach to the end of the test
- 1:05:30vectors.
- 1:05:33So, this is the code.
- 1:05:36In here, I have a clock and reset
- 1:05:39inputs, A, B, C inputs and Y expected
- 1:05:43uh value, [clears throat]
- 1:05:45uh
- 1:05:45logic Y output.
- 1:05:48Vector num
- 1:05:50corresponds to the number of the vectors
- 1:05:52and errors is number of errors we
- 1:05:55encountered.
- 1:05:56And
- 1:05:57uh test vectors is the For example, we
- 1:06:00will apply
- 1:06:01for example, in here 10,000 10,001 by
- 1:06:04the way, 0 to 10,000 means 10,001
- 1:06:07different test vectors.
- 1:06:09So, this is the array of test vectors.
- 1:06:11So, at each time
- 1:06:14for example, I will apply test vector 0
- 1:06:16and check the result is correct or not.
- 1:06:18And after that, in the next block, I
- 1:06:20will apply test vector 1, 2, 3 at every
- 1:06:23time and I will check the output.
- 1:06:25This is my model instantiation, uh the
- 1:06:28the function that I want to test.
- 1:06:31I instantiate it and connect A, B, C uh
- 1:06:34to here.
- 1:06:36Uh by the way, note that in test bench,
- 1:06:39there is no input and output.
- 1:06:41There is no input and output. Everything
- 1:06:43is signal in test bench because test
- 1:06:45bench is not a real model. It is just to
- 1:06:47check the whether my function is
- 1:06:50my model is correct or not. For this
- 1:06:52reason, it has no input and output
- 1:06:54concept because it is just We are using
- 1:06:56it just to test.
- 1:06:58So, these are the
- 1:07:00signals inside the test bench.
- 1:07:04>> [clears throat]
- 1:07:05>> So,
- 1:07:06in this block, we are generating a
- 1:07:08clock.
- 1:07:10So, we are generating clock in an always
- 1:07:12block. Always means that always run.
- 1:07:15It is not initial. Initial means that
- 1:07:17run only once,
- 1:07:19but always says that always run.
- 1:07:21How this generates clock? In this
- 1:07:24always, by the way, no sensitivity, so
- 1:07:27it always executes.
- 1:07:29So, this always block, for example,
- 1:07:31first this is a for example clock
- 1:07:33signal. This is a one bit signal.
- 1:07:36First, it assigns one to clock,
- 1:07:39and then waits five unit time.
- 1:07:42At five after five unit time, clock
- 1:07:44becomes Sorry, it was one at the
- 1:07:46beginning.
- 1:07:47At the beginning, it was one, and after
- 1:07:49five unit time, clock becoming zero, and
- 1:07:51after another five units of time, at 10,
- 1:07:55it becomes one again.
- 1:07:57And at 15, it becomes zero. So, it runs
- 1:08:00forever, so it generates a clock signal
- 1:08:03for sequential logic. This is how we are
- 1:08:05generating the clock.
- 1:08:07And we will continue We are continuing
- 1:08:09on the this module, test bench module.
- 1:08:13>> [clears throat]
- 1:08:13>> At the start of the test, we are loading
- 1:08:15the vectors and pass to apply the reset.
- 1:08:19So, how we are
- 1:08:20applying the test vectors? It is written
- 1:08:23in a file, as I told before. For
- 1:08:25example, in this
- 1:08:27file,
- 1:08:29in a such way,
- 1:08:30the file This is the test vectors file.
- 1:08:33It has a ABC inputs and expected Y
- 1:08:36output. We are applying this example
- 1:08:39test file to test vectors.
- 1:08:45And assume that in here, there are
- 1:08:4710,001
- 1:08:48tests.
- 1:08:50And vector num and errors are
- 1:08:52initialized as zero at the beginning,
- 1:08:54and I applied reset. If reset is one,
- 1:08:58uh I am starting from the beginning.
- 1:09:00There is a reset in here. And after 22
- 1:09:04unit time, I am releasing the reset.
- 1:09:06Reset is becoming zero. This is initial
- 1:09:09block. This is runs once only.
- 1:09:12If it comes here, then nothing change.
- 1:09:15This this block will not change run
- 1:09:16again.
- 1:09:20And in here, in always FF block, just
- 1:09:23write always FF. You can say always
- 1:09:25also, it is
- 1:09:26fine, but it's better to use always FF.
- 1:09:30At every clock, you are applying the
- 1:09:32test vectors on the rising edge of the
- 1:09:34clock.
- 1:09:36And
- 1:09:36>> [clears throat]
- 1:09:39>> for example, this is the test vectors we
- 1:09:41loaded from the file. And
- 1:09:43vector num is at each time, vector num
- 1:09:46will be increased by one. At the
- 1:09:48beginning, it was zero.
- 1:09:49And I'm getting the first test vector
- 1:09:51and applying it to ABCY expected.
- 1:09:56And after that, I am here in the negedge
- 1:09:59of the clock.
- 1:10:01In here, in the negedge of the clock, if
- 1:10:04there is no reset, I am checking whether
- 1:10:06Y is Y expected.
- 1:10:08And if there is an error, if not
- 1:10:10expected, I am giving an error.
- 1:10:13And increasing the error count one, but
- 1:10:15still continue.
- 1:10:18And this is the
- 1:10:20this is still always statement. It
- 1:10:22continues at each test, I am increasing
- 1:10:26the vector
- 1:10:27number one.
- 1:10:29And if I reach the end of the test
- 1:10:31vector, I am saying that I finished the
- 1:10:34test.
- 1:10:35And in here, there is a stop statement.
- 1:10:37Stop says that simulation needs to stop.
- 1:10:39This is a special also keyword. It says
- 1:10:42the simulation to stop.
- 1:10:45Uh
- 1:10:46by the way, as I told, we will release a
- 1:10:48video recordings to show how to use the
- 1:10:50Verilator.
- 1:10:51You will use a Verilator and do basic
- 1:10:54simulation. We will show it to you.
- 1:10:59In here, there is a
- 1:11:01comparison. Previously, we saw
- 1:11:03comparison as equal equal or not equal.
- 1:11:06Uh
- 1:11:07if you are using three equal
- 1:11:09or not
- 1:11:11uh equal equal, then this one also
- 1:11:14compares values
- 1:11:161 0 X and Z also. Normally,
- 1:11:19this one compares the value 1 or 0, but
- 1:11:22if you use three of them, three equal
- 1:11:25uh then you can compare the values
- 1:11:28whether it is X or Z also. It's more
- 1:11:30detailed comparison.
- 1:11:33So, that that's the end of the lecture.
- 1:11:36Uh do you have any any questions?
- 1:11:43So, if no question, in the next week,
- 1:11:45inshallah, we will start the RISC-V
- 1:11:47instruction set architecture.
- 1:11:51No question?
- 1:11:52Okay, then. See you.
About this transcript
This page contains the full transcript of W2 SystemVerilog Part2 EN by Hasan Erdem Yantır, generated from the public captions YouTube serves with the video. The transcript has 10,122 words across 1,759 segments, with the original timestamps preserved so you can click any line to jump to that moment in the embedded player.
What you can do with it
Use the transcript to take notes, quote the speaker, build a study guide, generate a summary with ChatGPT or Claude via the YouTube Summary tool, or export it as a timed subtitle file with YouTube to SRT. You can also re-open it in the transcriber to translate the transcript into 100+ languages.
Free YouTube transcript tool
YouTube2Text is a free YouTube transcript generator — no signup, no daily limit. Paste any YouTube link and get the full transcript instantly, with timestamps, click-to-jump, translation to 100+ languages, AI prompts for ChatGPT, Claude, and Gemini, and exports to TXT, SRT, VTT, or Markdown.