Donald E. Thomas - The Verilog Hardware Description Language, Fifth Edition (798541), страница 34
Текст из файла (страница 34)
If the value of the c’s taken together is 0, then there is nocorrection to be made. However, if the c’s take on a non-zero value, that value encodesthe bit number of the bit that is incorrect. This bit needs to be inverted. The c bits areinput to the deMux module which decodes them to one of eight possible data bits.These bits, assigned to the 8-wire vector bitFlippers, correspond to the bit positionthat needs to be inverted (a one indicates invert, and a zero indicates no inversion).The individual bits of bitFlippers are then inputs to eight XOR gates in xor8. Theother input of the XOR gates is the data bits to be corrected.
A one on a bitFlipper bitwill invert (correct) the corresponding data bit. The output of xor8 is the correcteddata and is the output of the hamDecode module.module testHam;reg[1:8] original;wire[1:8] regenerated;wire[1:12] encoded,messedUp;integerseed;initial beginseed = 1;forever beginoriginal =(seed);#1("original=%h, encoded=%h, messed=%h, regen=%h",original, encoded, messedUp, regenerated);endendhamEncodehamDecodehIn (original, encoded);hOut (messedUp, regenerated);assign messedUp = encoded ^ 12'b 0000_0010_0000;endmodulemodule hamEncode(input [1:8] vIn,output [1:12] valueOut);wire h1, h2, h4, h8;xor(h1, vIn[l], vIn[2], vIn[4], vIn[5], vIn[7]),Logic Level Modeling169(h2, vIn[l], vIn[3], vIn[4], vIn[6], vIn[7]),(h4, vIn[2], vIn[3], vIn[4], vIn[8]),(h8,vIn[5],vIn[6],vIn[7],vIn[8]);assign valueOut = {h1, h2, vIn[l], h4, vln[2:4], h8, vIn[5:8]};endmodulemodule xor8(output [1:8]input [1:8]xout,xin1,xin2);xor a[l:8] (xout, xin1, xin2);endmodulemodule hamDecode(input [1:12] vIn,output [1:8] valueOut);wirec1, c2, c4, c8;wire[1:8] bitFlippers;xor(c1, vIn[l], vIn[3], vIn[5], vIn[7], vIn[9], vIn[11]),(c2, vIn[2], vIn[3], vIn[6], vIn[7], vIn[10], vIn[11]),(c4, vIn[4], vIn[5], vIn[6], vIn[7], vIn[12]),(c8, vIn[8], vIn[9], vIn[10], vIn[l l], vIn[12]);deMux mux1 (bitFlippers, c1, c2, c4, c8,1'b1);xor8 x1 (valueOut, bitFlippers, {vIn[3], vIn[5], vIn[6], vIn[7], vIn[9],vIn[10],vIn[11],vIn[12]});endmodulemodule deMux(output [1:8] outVector,inputA, B, C, D, enable);andv(ml2, D, C, ~B, ~A, enable),h (m11, D, ~C, B, A, enable),d (m10, D, ~C, B, ~A, enable),1 (m9, D, ~C, ~B, A, enable),s(m7,~D,C,B, A, enable),u (m6, ~D, C, B, ~A, enable),c (m5, ~D, C, ~B, A, enable),ks (m3, ~D, ~C, B, A, enable);assign outVector = {m3, m5, m6, m7, m9, ml0, m11, m12};endmoduleExample 6.3 The Hamming Encode/Decode Example170The Verilog Hardware Description LanguageLooking more closely at module deMux, we see four select inputs (a - d) and anenable.
Input d corresponds to the 8’s place-value and a corresponds to the 1’s place.The purpose of this module is to generate an 8-bit vector that has at most one bit set.That one bit corresponds to the encoded bit that needs to be corrected. Since we areonly going to correct the data bits, only the necessary minterms of bits a-d are generated. These are: 3, 5, 6, 7, 9, 10, 11, and 12, which correspond to the encoded bitpositions of the data in Figure 6.2. The AND gates generate the minterms and theassign statement concatenates these minterms together into outVector.BitFlippers, the output of deMux, is input to xor8. These input bits (input xin1)along with bits 3, 5, 6, 7, 9, 10, 11, and 12 of the encoded data (input xin2) are inputsto eight XOR gates.
Thus, an incorrect input bit, indicated by a one in one of the bits ofxinl, will cause that bit to be inverted by the XOR gates. The output of xor8 is also theoutput of hamDecode.Returning to module hamTest, we see that original is the input to hamEncode andthat encoded is its output. Encoded is then the input to the assign statement whichproduces messedUp. The purpose of the assign statement is to simulate a noisy channel where one of the input bits gets inverted. In this case bit 7 is inverted.
The outputof the assign (messedUp) is input to hamDecode which corrects this inversion andproduces the original data on regenerated.The only procedural statements in the whole example are in the initial statement ofthis module. Their purpose is to run test vectors through the system. To do this, weuse thesystem task to produce random numbers. Here, we set the seed valueforto 1 and enter a forever loop. Original is loaded with the result ofThe output of original drives the hamEncode module.
None of the gate primitives or wires have delays associated with them, so regenerated is produced in zerosimulation time. Our forever loop delays 1 time unit to insure regenerated is produced and then displays all of the inter-module values as shown in Figure 6.4. Consider the first row of the figure. The original data is 00 which is encoded as 000. Theassign statement inverts bit 7 producing 020. (In this example, the bits are countedfrom the left starting with 1 and thetask specifies hexadecimal.) The bit isthen corrected producing the original data.There are several features to note in this example:Seed is declared to be an integer.
Integers are often used for ancillary calculationsin a simulation model. In a real design, this value would not exist as it is only therefor testing purposes. Registers should be used when modeling real parts of hardware. See Appendix E for more discussion on integers.This use of thesystem task requests printing in hexadecimal with the“%h” printing control. See Appendix F for more discussion of thetask.Logic Level ModelingReferences:F.1;171F.76.3 Continuous AssignmentContinuous assignments provide a means to abstractly model combinational hardwaredriving values onto nets.
An alternate version of the one-bit full adder in the previoussection is shown using continuous assignments in Example 6.4. Here we show thetwo outputs sum and cOut being described with an assign statement. The first (sum)is the exclusive-or of the three inputs, and the second is the majority function of thethree inputs.module oneBitFullAdder(output cOut, sum,input aIn, bIn, cIn);assignsum = aIn ^ bIn ^ cIn,cOut = (aIn & bIn) (bIn & cIn) (aIn & cIn);endmoduleExample 6.4 Illustration of Continuous AssignmentThe continuous assignment is different from the procedural assignment presentedin the chapters on behavioral modeling.
The continuous assignment is always active(driving a 0, , x, or z), regardless of any state sequence in the circuit. If any input toThe Verilog Hardware Description Language172the assign statement changes at any time, the assign statement will be reevaluated andthe output will be propagated.
This is a characteristic of combinational logic and alsoof the Verilog gate level timing model.The general form of the assign statement is:continuous_assignassign [drive_strength] [delay3] list_of_net_assignments ;list_of_net_assignmentsnet_assignment {, net_assignment }net_assigmnentnet_lvalue = expressionwhere assign is a keyword, the drive_strength and delay3 specifications are optionalparts, and the list_of_net_assignments takes the form of a comma-separated list asshown in Example 6.4. The drive strength of a continuous assign defaults to strong0and strong1 and can be specified for assignments to scalar nets of any type except typesupply0 and supplyl.
The delay defaults to 0. If undeclared, the left-hand side isimplicitly declared a net. The above assign could have been written as shown below:assign (strong0, strong1)sum = aIn ^ bIn ^ cIn,cOut = (aIn & bIn) | (bIn & cIn) | (aIn & cIn);Here we specify that both of the continuous assignments have the default drivestrength.References: delay modeling 6.5 and 6.6; strength modeling 10; timing models 8.16.3.1 Behavioral Modeling of Combinational CircuitsThe continuous assign provides a means of abstracting from a gate level model of acircuit. In this sense, the continuous assign is a form of behavioral modeling for combinational circuits. That is, we only need specify the Boolean algebra of the logicfunction, not its actual gate level implementation.
The final gate level implementationis then left to a logic synthesis program or further designer effort.Logic Level ModelingThe right-hand side expressionin the assign statement may containa function call to a Verilog function.Recall that within a function, wemay have procedural statementssuch as case and looping statements, but not wait, @event, or#delay. Thus we may use proceduralstatements to describe a complexcombinational logic function.
Forinstance, in Example 6.5 a description of a multiplexor illustrates afunction call in an assign.173module multiplexor(inputa, b, c, d,input [1:0] select,outpute);assign e = mux (a, b, c, d, select);function mux(inputa, b, c, d,input [l:0]select);case (select)2'b00:2'b0l:2'b10:2'bl l:default:endcaseendfunctionendmodulemux = a;mux = b;mux = c;mux = d;mux = 'bx;In this example, module multiplexor has a continuous assignmentwhich calls function mux. Thefunction uses the procedural casestatement to describe the behaviorof the combinational multiplexingfunction.
If one of the case expressions match the controlling expres- Example 6.5 Function Call From ContinuousAssignmentsion, then mux is assigned theappropriate value. If none of thefirst four match (e.g. there is an x or z on a select input), then by default, mux isassigned to carry the unknown value x.Although the assign statement provides access to an assortment of proceduralstatements for behaviorally describing combinational hardware, we must be cognizantof different levels of abstraction in behavioral modeling.
At a high level of abstractionwe have the process that models sequential activity as described in Chapters 3 and 4.At that level, we are describing a situation which involves a separate thread of controland the implementation will typically have its own internal state machine watchingfor changes on its inputs. To model this, we would define a module with an alwaysstatement and communicate with it through module ports and with the interprocesswait and event statements. Clearly, this is not the modeling situation of Example 6.5where we are only describing a combinational multiplexor which gates one of itsinputs to its output without the need for an internal state machine to control it.Rather, at this lower level of abstraction we model combinational behavior whichdoes not contain its own internal state.