Why are the bits in this Verilog wire assigned as 'z'? - binary

I am trying to create a multiplication module in Verilog for an ALU project.
When I pass test values to this modules, 0100101010011100 and 0100110000000000 and print these values with $display(), they appear normal. However, if I try to print one of my calculated values like p0-p15, it shows 16bits of z. I don't understand why this is happening, because it appears I am assigning {16{inputA[0]}} & inputB[15:0] which shows valid results when I print it out.
The only conclusion that I can come to is that I am either calling this module improperly, or assigning the values improperly.
Should I be using reg instead of wires for the 15 'p' variables?
module Product(inputA, inputB, Output);
input [15:0] inputA, inputB;
output [31:0] Output;
//calculate 16 subproducts
wire [15:0] p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15;
//assign p0[15:0] = {16{inputA[0]}} & inputB[15:0];
assign p0[15:0] = {16{inputA[0]}} & inputB[15:0];
assign p1[15:0] = {16{inputA[1]}} & inputB[15:0];
assign p2[15:0] = {16{inputA[2]}} & inputB[15:0];
assign p3[15:0] = {16{inputA[3]}} & inputB[15:0];
assign p4[15:0] = {16{inputA[4]}} & inputB[15:0];
assign p5[15:0] = {16{inputA[5]}} & inputB[15:0];
assign p6[15:0] = {16{inputA[6]}} & inputB[15:0];
assign p7[15:0] = {16{inputA[7]}} & inputB[15:0];
assign p8[15:0] = {16{inputA[8]}} & inputB[15:0];
assign p9[15:0] = {16{inputA[9]}} & inputB[15:0];
assign p10[15:0] = {16{inputA[10]}} & inputB[15:0];
assign p11[15:0] = {16{inputA[11]}} & inputB[15:0];
assign p12[15:0] = {16{inputA[12]}} & inputB[15:0];
assign p13[15:0] = {16{inputA[13]}} & inputB[15:0];
assign p14[15:0] = {16{inputA[14]}} & inputB[15:0];
assign p15[15:0] = {16{inputA[15]}} & inputB[15:0];
initial begin
$display("%b",inputA);
$display("%b",inputB);
$display("----------------");
$display("%b", {16{inputA[0]}} & inputB[15:0]);
$display("%b", {16{inputA[1]}} & inputB[15:0]);
$display("%b", {16{inputA[2]}} & inputB[15:0]);
$display("%b", {16{inputA[3]}} & inputB[15:0]);
$display("%b", {16{inputA[4]}} & inputB[15:0]);
$display("%b", {16{inputA[5]}} & inputB[15:0]);
$display("%b", {16{inputA[6]}} & inputB[15:0]);
$display("%b", {16{inputA[7]}} & inputB[15:0]);
$display("%b", {16{inputA[8]}} & inputB[15:0]);
$display("%b", {16{inputA[9]}} & inputB[15:0]);
$display("%b", {16{inputA[10]}} & inputB[15:0]);
$display("%b", {16{inputA[11]}} & inputB[15:0]);
$display("%b", {16{inputA[12]}} & inputB[15:0]);
$display("%b", {16{inputA[13]}} & inputB[15:0]);
$display("%b", {16{inputA[14]}} & inputB[15:0]);
$display("%b", {16{inputA[15]}} & inputB[15:0]);
$display("----------------");
$display("%b",p0);
$display("%b",p1);
$display("%b",p2);
$display("%b",p3);
$display("%b",p4);
$display("%b",p5);
$display("%b",p6);
$display("%b",p7);
$display("%b",p8);
$display("%b",p9);
$display("%b",p10);
$display("%b",p11);
$display("%b",p12);
$display("%b",p13);
$display("%b",p14);
$display("%b",p15);
$display("----------------");
end
wire [31:0] s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15;
assign s0[31:0] = p0 << 0;
assign s1[31:0] = p1 << 1;
assign s2[31:0] = p2 << 2;
assign s3[31:0] = p3 << 3;
assign s4[31:0] = p4 << 4;
assign s5[31:0] = p5 << 5;
assign s6[31:0] = p6 << 6;
assign s7[31:0] = p7 << 7;
assign s8[31:0] = p8 << 8;
assign s9[31:0] = p9 << 9;
assign s10[31:0] = p10 << 10;
assign s11[31:0] = p11 << 11;
assign s12[31:0] = p12 << 12;
assign s13[31:0] = p13 << 13;
assign s14[31:0] = p14 << 14;
assign s15[31:0] = p15 << 15;
end module
module testbench();
reg [4:0] i;
parameter n=16;
reg [15:0] inputA;
reg [15:0] inputB;
reg [4:0] opcode;
wire [31:0] out1;
wire [1:0] out2;
wire [15:0] a,b;
assign a =16'b0100_1010_1001_1100;
assign b =16'b0100_1100_0000_0000;
Product prod(a, b, out1);
endmodule

This is a time-0 race condition because you have not given enough time for the inputs to propagate to the outputs. Other simulators show non-z results. You can add a #1 before you display any of your signals.
In general simulation needs time to propagate all statements that happen concurrently.

Related

VBScript: Addition producing a negative number

I am updating an old VBScript. I was trying to add two variables together in a VBScript function I'm working on, one is a negative while the other is a positive but when the number gets sent back to the SQL table it doesn't calculate correctly. I have code that is similar to this that function correctly when you subtract
EX:-76+4 ends up being -80 instead of -72.
here is code maybe something is wrong with variable.
strSQL = "UPDATE Parts SET On_Hand = '"
strSQL = strSQL & (CInt(objRS("On_Hand")) + CInt(Request.Form("QtyIssued"))) & "'"
strSQL = strSQL & "WHERE Part_ID = '" & Request.Form("PartNum" & x) & "';"
Note: I have change Cint from Ccur and still didn't work.
On_Hand is also a float in the table.
EDIT: Added full code for clarity
strSQL = "UPDATE Parts SET On_Hand = '"
strSQL = strSQL & (CInt(objRS("On_Hand")) + CInt(Request.Form("QtyIssued"))) & "'"
strSQL = strSQL & "WHERE Part_ID = '" & Request.Form("PartNum" & x) & "';"
Response.Write strSQL & "<br>"
objRS.close
objRS.Open strSQL, objConn
Here is Response Write:
UPDATE Parts SET On_Hand = '-80'WHERE Part_ID = '15-0219';
You need to check your input values coming from the form, as a simple test can debunk your theory that the calculation is wrong.
<%
Dim sum
Dim x, y
x = -76
y = 4
sum = x + y
Call Response.Write(sum)
Call Response.Write("<br />")
x = "-76"
y = "4"
sum = CInt(x) + CInt(y)
Call Response.Write(sum)
%>
Output:
-72
-72

Import CSV and force all fields to Text format

I am importing a series of CSV files into Access tables. I have the following line that imports each file:
DoCmd.TransferText acImportDelim, , FN, F.Path, True
This import statement works and creates the necessary table. However, it creates the field types from the data, and depending on the first few rows of the data it may create a field as numeric that should be text - and then causes an error when it encounters a text value later in the file.
How can I force the field type to Text for every field in the input file? I've used Import Specifications before, but first the file format (provided by others outside my control) may change from time to time, and second it's a very "wide" file with 200+ column, so this isn't a practical answer.
This is not a great workaround, but I had to go through the process anyway to get around the 255 field limit in tables. In short, the import steps I ended up with are
Read the 1st line of the file as an inputstream
Split the line to get the field names, put them in a data dictionary table and then manually mark the ones I want to import
Use CREATE TABLE to create a new data table (selected fields only) with all of the fields set to TEXT
Read each line of the file as an inputstream
Split the line to get the data for each field
Use INSERT INTO to add the selected fields to the data table
Cumbersome, but it solves both problems - I'm not limited to 255 fields in the input files and I can control the data type of the fields as I create them.
The code, if anyone cares, is
Function Layout()
Set db = CurrentDb()
Folder = DLookup("[data folder]", "folder")
Dim FSO As New FileSystemObject
Set flist = FSO.GetFolder(Folder).Files
db.Execute ("delete * from [data dictionary]")
For Each F In flist
FN = Left(F.Name, InStr(F.Name, ".") - 1)
FT = Mid(F.Name, InStr(F.Name, ".") + 1)
If FT <> "csv" Then GoTo Skip
If TestFile(F.path) = "ASCII" Then
Set instream = FSO.OpenTextFile(F.path, ForReading, , 0)
Else: Set instream = FSO.OpenTextFile(F.path, ForReading, , -1)
End If
header = instream.ReadLine
Data = Split(header, ",")
For i = LBound(Data) To UBound(Data)
SQL = "insert into [data dictionary] ([table], [field], [index]) select "
SQL = SQL & "'" & FN & "','" & Data(i) & "','" & i & "'"
db.Execute SQL
Next i
Skip: Next F
End Function
Function TestFile(ByVal path As String)
Dim buffer As String
Dim InFileNum As Integer
Dim firstByte As Integer
Dim secondByte As Integer
Dim thirdByte As Integer
buffer = String(100, " ")
InFileNum = FreeFile
Open path For Binary Access Read As InFileNum
Get InFileNum, , buffer
Close InFileNum
firstByte = Asc(Mid(buffer, 1, 1))
secondByte = Asc(Mid(buffer, 2, 1))
thirdByte = Asc(Mid(buffer, 3, 1))
If (firstByte = 255 And secondByte = 254) Then
TestFile = "Unicode"
ElseIf (firstByte = 254 And secondByte = 255) Then
TestFile = "Unicode"
ElseIf (firstByte = 239 And secondByte = 187 And thirdByte = 191) Then
TestFile = "Unicode"
Else
TestFile = "ASCII"
End If
End Function
Function import()
Folder = DLookup("[data folder]", "folder")
Set db = CurrentDb()
Dim FSO As New FileSystemObject
Set Tlist = db.OpenRecordset("select [table] from [data dictionary] where ([required]<>'') group by [table]")
Tlist.MoveFirst
Do While Not Tlist.EOF
TN = Tlist.Fields("table").Value
Delete_table (TN)
Set flist = db.OpenRecordset("select * from [data dictionary] where [required]<>'' and [table]='" & TN & "'")
flist.MoveFirst
Text = ""
Do While Not flist.EOF
FN = flist.Fields("Field")
Text = Text & "," & FN & " " & IIf(InStr(FN, "Date") > 0 Or InStr(FN, "_DT") > 0, "DATETIME", "TEXT")
flist.MoveNext
Loop
SQL = "CREATE TABLE " & TN & "(" & Mid(Text, 2) & ")"
db.Execute SQL
path = Folder & "\" & TN & ".csv"
If TestFile(path) = "ASCII" Then
Set instream = FSO.OpenTextFile(path, ForReading, , 0)
Else: Set instream = FSO.OpenTextFile(path, ForReading, , -1)
End If
header = instream.ReadLine
Do While Not instream.AtEndOfStream
Line = parser(instream.ReadLine)
Data = Split(Line, ",")
flist.MoveFirst
Text = ""
Do While Not flist.EOF
n = flist.Fields("index").Value
Text = Text & ",'" & Data(n) & "'"
flist.MoveNext
Loop
SQL = "insert into [" & TN & "] values(" & Mid(Text, 2) & ")"
db.Execute SQL
Loop
Tlist.MoveNext
Loop
x = MultipleCodes()
MsgBox ("done")
End Function
Function parser(S)
parser = S
i = InStr(S, Chr(34))
If i = 0 Then
parser = S
Else
j = InStr(i + 1, S, Chr(34))
T = Mid(S, i + 1, j - i - 1)
T = Replace(T, ",", ";")
parser = Left(S, i - 1) & T & parser(Mid(S, j + 1))
End If
End Function

MS Access VB: How do I update a table with a parametrized query ONLY with textboxes that are not empty?

I have some VBA code that will update a table based on a form. It works great, except that I want the table to only update wherever the user fill in info. If that textbox is instead blank, do no update that field in the table. Below is the working update code. The line that starts with If query.Parameters("P1")... is my attempt at trying to make an If statement that will find which textbox values are Null and then ignore those, but I don't know if that's even going in the right direction.
Private Sub Command133_Click()
'Update row for downtime
Dim dbsCurrent As Database
Set dbsCurrent = CurrentDb
', suffix, production_date, reason, downtime_minutes, comment ,'" & CInt(Me.Text118) & "','" & CDate(Me.Text126) & "','" & Me.Text121 & "','" & CDbl(Me.Text123) & "','" & Me.Text128 & "'
'dbsCurrent.Execute " INSERT INTO tbl_Downtime (production_date) SELECT #" & Me.Text126 & "# FROM tbl_Downtime As t WHERE t.ID = " & Me.Text135 & ";"
'dbsCurrent.Execute "UPDATE tbl_Downtime SET job = '" & Me.Text116 & "', suffix = '" & Me.Text118 & "', production_date = #" & Me.Text126 & "#, reason = '" & Me.Text121 & "', downtime_minutes = " & Me.Text123 & ", comment = '" & Me.Text128 & "', shift = '" & Me.Text144 & "' WHERE t.ID = " & Me.Text135 & ";"
Dim query As QueryDef
Dim sql As String
For Each query In CurrentDb.QueryDefs
If query.Name = "UpdateDowntime" Then
Exit For
End If
Next query
If query Is Nothing Then
sql = "parameters " & _
"P1 text, P2 text, P3 Date, P4 Text, P5 Number, P6 Text, P7 Text, P8 Number;" & _
"UPDATE [tbl_Downtime] " & _
"SET job = [P1], suffix = [P2], production_date = [P3], reason = [P4], downtime_minutes = [P5], comment = [P6], shift = [P7] " & _
"WHERE[tbl_Downtime].id = [P8]"
'"(job, suffix, production_date, reason, downtime_minutes, comment, shift) " & _
'" VALUES ([P1], [P2], [P3], [P4], [P5], [P6], [P7]) WHERE[tbl_Downtime].id = [P8]"
Set query = CurrentDb.CreateQueryDef("UpdateDowntime", sql)
End If
query.Parameters("P1").Value = Me.Text116
query.Parameters("P2").Value = Me.Text118
query.Parameters("P3").Value = Me.Text126
query.Parameters("P4").Value = Me.Text121
query.Parameters("P5").Value = Me.Text123
query.Parameters("P6").Value = Me.Text128
query.Parameters("P7").Value = Me.Text144
query.Parameters("P8").Value = Me.Text135
If query.Parameters("P1").Value = "" Then Set query.Parameters("P1").Value = job End If ' WHERE [tbl_Downtime].id = [P8] END
query.Execute
An empty string is not the same as a null value in a database, so you need to change the parameter value to nothing if you want it to equate to null (or default value if one exists).
You could either conditionally set the parameter value like this:
If textbox1.text <> "" then
query.Parameters("P1").Value = textbox1.text
End if
or you could write a function to set the parameter to nothing if the textbox is empty:
Function NothingIfEmpty(value As String)
If value = "" Then
NothingIfEmpty = Nothing
Else
NothingIfEmpty = value
End If
End Function
and use it like this:
query.Parameters("P1").Value = NothingIfEmpty(textbox1.text)
query.Parameters("P2").Value = NothingIfEmpty(textbox2.text)
You can do it this way:
"SET job = Nz([P1], job), suffix = Nz([P2], suffix), production_date = Nz([P3], production_date), reason = Nz([P4], reason), downtime_minutes = Nz([P5], downtime_minutes), comment = Nz([P6], comment), shift = Nz([P7], shift) " & _
"WHERE [tbl_Downtime].id = Nz([P8], -[id])"

How to convert currency into double in VBA?

I have three textboxes and I get their value like this:
Dim X, Y, W As Double
X = DLookup("Summ", "tblPlatej", "ID= " & Form_frmPlatej!ID)
Y = DLookup("Deposit_before", "tblPlatej", "ID= " & Form_frmPlatej!ID)
W = DLookup("Monthly_payment", "tblPlatej", "ID= " & Form_frmPlatej!ID)
But when I change the value of textbox like this
Form_frmPlatej.Deposit_before = X - W + Y
I get a Type mismatch error. All textboxes are currency. How do I calculate new record and put that number in the "Deposit_before" textbox?
Summ, Deposit_before, Monthly_payment are currency data type in my table. Deposit_before is mostly negative.
Here is my whole code for button click
Private Sub Command13_Click()
a1 = DLookup("Inhabitant", "tblClient", "ID = " & Form_frmMain!ID)
B1 = DLookup("PriceTBO", "tblPrice")
c1 = DLookup("Republican", "tblClient", "ID = " & Form_frmMain!ID)
d1 = DLookup("Regional", "tblClient", "ID = " & Form_frmMain!ID)
e1 = DLookup("Local", "tblClient", "ID = " & Form_frmMain!ID)
A = DLookup("IDP", "tblPlatej", "ID= " & Form_frmPlatej!ID)
B = DLookup("Type_of_payment", "tblPlatej", "ID= " & Form_frmPlatej!ID)
C = DLookup("Year", "tblPlatej", "ID= " & Form_frmPlatej!ID)
D = DLookup("Month", "tblPlatej", "ID= " & Form_frmPlatej!ID)
Y = DLookup("Deposit_before", "tblPlatej", "ID= " & Form_frmPlatej!ID) // Problem here
W = DLookup("Monthly_payment", "tblPlatej", "ID= " & Form_frmPlatej!ID) //Problem here
X = DLookup("Summ", "tblPlatej", "ID= " & Form_frmPlatej!ID)
i = Form_frmPlatej.Month.ListIndex
j = Form_frmPlatej.Year.ListIndex
den = DLookup("Date", "tblPlatej", "IDP = " & Form_frmPlatej!IDP)
If X <> " " Then
With Me.Recordset
If Me.Recordset.BOF = False And Me.Recordset.EOF = False Then
.MoveFirst
End If
.AddNew
.Edit
Form_frmPlatej.Deposit_before = X - W + Y //Problem here
Form_frmPlatej.IDP = A + 1
Form_frmPlatej.Type_of_payment = B
If i = 11 Then
Form_frmPlatej.Year = Year.ItemData(j + 1)
i = -1
Else
Form_frmPlatej.Year = Year.ItemData(j)
End If
Form_frmPlatej.Month = Month.ItemData(i + 1)
Form_frmPlatej.Date = DateAdd("m", 1, den)
If c1 <> 0 Then
Form_frmPlatej.Monthly_payment = (a1 * B1) - (c1 * (a1 * B1)) / 100
ElseIf d1 <> 0 Then
Form_frmPlatej.Monthly_payment = (a1 * B1) - (d1 * (a1 * B1)) / 100
ElseIf e1 <> 0 Then
Form_frmPlatej.Monthly_payment = (a1 * B1) - (e1 * (a1 * B1)) / 100
Else
Form_frmPlatej.Monthly_payment = a1 * B1
End If
.Update
End With
Else
MsgBox ("Please enter number")
End If
End Sub
I am completely confused.
I bet your problem is the following. When you say this:
Dim X, Y, W As Double
you think you've done this:
Dim X As Double, Y As Double, W As Double
but what you've really done is this:
Dim X
Dim Y
Dim W As Double
This is a classic VBA mistake. Most VBA programmers have made it, and that's why most VBA programmers fall back on declaring only one variable per Dim statement (i.e. one per line). Otherwise it's way too easy to make that mistake, and difficult to spot it afterwards.
So with Dim X and Dim Y you've implicitly declared X and Y as Variant type (equivalent to Dim X As Variant and Dim Y As Variant).
Why does this matter? When you then say this:
X = DLookup("Summ", "tblPlatej", "ID= " & Form_frmPlatej!ID)
Y = DLookup("Deposit_before", "tblPlatej", "ID= " & Form_frmPlatej!ID)
maybe one of those two DLookup unexpectedly returns something that isn't a number, for example a string. Your variant X or Y will accept this without complaining; the Variant acquires the type of the thing on the right hand side of the assignment.
However, when you try to do math with these values, X - W + Y will throw a type mismatch error if X and/or Y is a string.
See also this earlier answer of mine, from which I reused some of the wording: https://stackoverflow.com/a/11089684/119775

Excel VBA - Running SQL script multiple times with different variable value

I want to run a script in my macro multiple times by changing variable values.
Below is an example of my code that I run for one value.
The line of code I would like to change is
sScript = sScript + "where m.outletid in ('" & sOutletId & "') " & vbCrLf
Sometime I want the where clause to be
where m.outletid in ('12314')
or
where m.chainid in ('411')...
Code:
Sub Report()
Dim sScript As String
Dim sServer As String
Dim sDatabase As String
Dim sTransTable As String
Dim iVal As Integer
Dim iReturnVal As Integer
Dim SheetExists As Worksheet
Dim WK_SHEET As String
sServer = Trim(UserForm1.txtServer.Value)
sDatabase = Trim(UserForm1.txtDatabase.Value)
sTransTable = Trim(UserForm1.txtTransTable.Value)
For Each SheetExists In Worksheets
If SheetExists.Name = ("Report") Then
Application.DisplayAlerts = False
Sheets("Report").Delete
Application.DisplayAlerts = True
Exit For
End If
Next SheetExists
Worksheets.Add after:=Sheets("Sheet1")
ActiveSheet.Name = ("Report")
WK_SHEET = "Report"
Sheets(WK_SHEET).Select
sOutletId = "12314"
sScript = "Select top 10 m.CustNumber, m.Name, sum(t.Transvalue) " & vbCrLf
sScript = sScript + "from " & sTransTable & " t " & vbCrLf
sScript = sScript + "where m.outletid in ('" & sOutletId & "') " & vbCrLf
sScript = sScript + "Group by m.CustNumber, m.Name " & vbCrLf
sScript = sScript + "order by sum(t.Transvalue)Desc " & vbCrLf
iReply = MsgBox(Prompt:="Do you wish to continue with the following script for Top 10 Customers?" + sScript + "", _
Buttons:=vbYesNo, Title:="Run MACRO Top 10 Reports")
If iReply = vbNo Then
End
End If
iVal = execute_sql_select(WK_SHEET, 2, 1, sServer, sDatabase, sScript)
Sheets(WK_SHEET).Name = "Outlet" & sOutletId & "Top 10 by Spend"
Now I would like to re run the above with OutletId 12315...how can I do this? Do I use some sort of loop?
You can keep list of OutletId into Array. Then get each OutletId from Array (for loop) and execute your sql script.
Pseudu code
Array listOutid = new Array[12,13,14,15];
for(int idx = 0; idx < listOutid.Length; idx++)
{
var OutletId = listOutid[idx];
//put ur sql statement and execute here..
}