program MaxMin;
#include("stdlib.hhf")
static
count: int32:=0;
input: int32;
maxVal: int32;
minVal: int32;
sum: int32:=0;
boolVar : boolean:= true;
begin MaxMin;
while(boolVar) do
stdout.put("Enter a number, 0 to stop:");
stdin.get(input);
if(input==0)then
break;
elseif(count == 0)then
maxVal=input;
minVal=input;
elseif(input>maxVal)then
maxVal=input;
elseif(input<minVal)then
minVal=input;
endif;
add(input,sum);
add(1,count);
endwhile;
stdout.newln();
stdout.put("Total: ",sum,nl,"Count: ",count,nl,"Maximum: ",maxVal,nl,"Minimum: ",minVal,nl);
end MaxMin;
ENVIRONMENT
HLA (High Level Assembler - HLABE back end, LD linker)
Version 2.16 build 4409 (prototype)
Ubuntu 20.04.1
SOLUTION
The problem is maxVal=input; is an invalid statement in HLA. To correct this problem us the mov instruction as follows: mov(input, maxVal);.
However, after this correction you will see the following error:
Assembling "src.hla" to "src.o"
Error in file "src.hla" at line 27 [errid:102032/hlaparse.bsn]:
Memory to memory comparisons are illegal.
Near: << ) >>
hlaparse: oututils.c:2480: FreeOperand: Assertion `o->l.leftOperand != ((void *)0)' failed.
Aborted (core dumped)
This is because HLA does not support comparison between memory objects. One solution is to store the user entered number in EAX and change all occurrences of the input variable to EAX.
EXAMPLE
program MaxMin;
#include("stdlib.hhf")
storage
maxVal: int32;
minVal: int32;
static
count: int32:= 0;
sum: int32:= 0;
boolVar: boolean:= true;
begin MaxMin;
while(boolVar) do
stdout.put("Enter a number, 0 to stop: ");
stdin.geti32();
if (EAX = 0 ) then
break;
elseif ( count = 0 ) then
mov(EAX, maxVal);
mov(EAX, minVal);
elseif (EAX > maxVal) then
mov(EAX, maxVal);
elseif (EAX < minVal) then
mov(EAX, minVal);
endif;
add(EAX, sum);
add(1, count);
endwhile;
stdout.newln();
stdout.put("Total: ",sum,nl,"Count: ",count,nl,"Maximum: ",maxVal,nl,"Minimum: ",minVal,nl);
end MaxMin;
Related
I wrote this Verilog code on modelSim.
module my_fsm (clock , reset , in , out);
input clock , reset , in;
output out;
wire clock , reset , in;
reg out;
reg [1:0] state; // state of the machine in case reset = 0
// A = 00 , B = 01 , C = 10 , D = don't care = 11
always #(posedge clock) begin
if (reset == 1'b1)
begin
state <= 2'b00;
out <= 1'b0;
end
else
begin
case (state)
2'b00:
out <= 1'b0;
if (in == 1'b1) state <= 2'b01;
2'b01:
out <= in;
if (in == 1'b0) state <= 2'b10;
if (in == 1'b1) state <= 2'b00;
2'b10:
out <= 1'b1;
if (in == 1'b0) state <= 2'b01;
default: out <= 1'bX;
endcase
end
end
endmodule
But the compiler is giving me this compilation errors:
** Error: (vlog-13069) C:/Users/michael/Documents/Logic Design/hw1/my_fsm .v(22): near "if": syntax error, unexpected if.
** Error: (vlog-13069) C:/Users/michael/Documents/Logic Design/hw1/my_fsm .v(27): near "2": syntax error, unexpected INTEGER NUMBER.
** Error: (vlog-13069) C:/Users/michael/Documents/Logic Design/hw1/my_fsm .v(30): near "default": syntax error, unexpected default.
I have looked up for those problems but couldn't find any solution for them.
Thank you,
Michael
Multiple statements in a branch of a case statement should be enclosed between begin and end. (Just like in an if statement, just like you've done in your if (reset == 1'b1) statement.)
I have an interrupt service routine that contains the variable count and a variable state that changes when count reaches a certain value.
What I want my code to do is change and maintain state for a certain period of time determined by the value of count in the if statements in the ISR.
e.g. I want the variable state to equal 1 for 10 counts;
I want state to equal 0 for 5 counts.
Somewhat similar to changing the duty cycle of a PWM.
The problem I am having is that the variable state resets to zero around the end of the ISR or the end of the if statement, I'm not sure.
After searching for answers, I have found that it might be related to the gcc compiler's optimisation but I cannot find a fix for this problem besides declaring volatile variables, which I have already done.
Any help is appreciated thanks.
My code:
#include <avr/io.h>
#include <avr/interrupt.h>
volatile int count = 0;
volatile int state = 0;
int main(void)
{
cli();
DDRB |= (1 << PB2);
TCCR0B |= (1 << CS02)|(0 << CS01)|(1 << CS00);
TIMSK |= (1 << TOIE0);
sei();
while(1) {
...
}
}
ISR(TIM0_OVF_vect)
{
cli();
// user code here
count = count + 1;
if ((count > 5) && (state < 1) && !(PORTB & (1 << PB2))) {
state = 1;
count = 0;
}
else if ((count > 10) && (state > 0) && (PORTB & (1 << PB2))) {
state = 0;
count = 0;
}
sei();
}
First of all your cli() has no effect in your ISR. When an interrupt happens the I flag automatically cleared and restored at the end of ISR - so sei() is needless as well. However there is rational case when sei() inserted somewhere in the middle of an ISR service to let other ISR's to interrupt it. Though it is not beginner level to build such sophisticated ISR system.
Second: if you set up a conditional structure the elementary conditions should be chained by double operators. The evaluation of (count > 5) & (state < 1) cannot be predicted, correctly written it is (count > 5) && (state < 1). Obviously for 'or'-ing || is used.
The conditions of the if statements look suspicious if you are mimicking a PWM.
Why is the pin of port B being tested? The bodies of the if statements will only be entered if the pin (button) is pressed with the correct frequency.
Do you mean to set the pin on port B instead? Then you would want
count = count + 1;
if ((count > 5) && (state < 1)) {
PORTB &= ~(1 << PB2); // clears PB2
state = 1;
count = 0;
}
else if ((count > 10) && (state > 0)) {
PORTB |= 1 << PB2; // sets PB2
state = 0;
count = 0;
}
I seem to have some issues anytime I try anything with I/O for verilog. Modelsim either throws function not supported for certain functions or does nothing at all. I simply need to read a file character by character and send each bit through the port. Can anyone assist
module readFile(clk,reset,dEnable,dataOut,done);
parameter size = 4;
//to Comply with S-block rules which is a 4x4 array will multiply by
// size so row is the number of size bits wide
parameter bits = 8*size;
input clk,reset,dEnable;
output dataOut,done;
wire [1:0] dEnable;
reg dataOut,done;
reg [7:0] addr;
integer file;
reg [31:0] c;
reg eof;
always#(posedge clk)
begin
if(file == 0 && dEnable == 2'b10)begin
file = $fopen("test.kyle");
end
end
always#(posedge clk) begin
if(addr>=32 || done==1'b1)begin
c <= $fgetc(file);
// c <= $getc();
eof <= $feof(file);
addr <= 0;
end
end
always#(posedge clk)
begin
if(dEnable == 2'b10)begin
if($feof(file))
done <= 1'b1;
else
addr <= addr+1;
end
end
//done this way because blocking statements should not really be used
always#(addr)
begin:Access_Data
if(reset == 1'b0) begin
dataOut <= 1'bx;
file <= 0;
end
else if(addr<32)
dataOut <= c[31-addr];
end
endmodule
I would suggest reading the entire file at one time into an array, and then iterate over the array to output the values.
Here is a snippet of how to read bytes from a file into a SystemVerilog queue. If you need to stick to plain old Verilog you can do the same thing with a regular array.
reg [8:0] c;
byte q[$];
int i;
// Read file a char at a time
file = $fopen("filename", "r");
c = $fgetc(file);
while (c != 'h1ff) begin
q.push_back(c);
$display("Got char [%0d] 0x%0h", i++, c);
c = $fgetc(file);
end
Note that c is defined as a 9-bit reg. The reason for is that $fgetc will return -1 when it reaches the end of the file. In order to differentiate between EOF and a valid 0xFF you need this extra bit.
I'm not familiar with $feof and don't see it in the Verilog 2001 spec, so that may be something specific to Modelsim. Or it could be the source of the "function not supported."
I am trying to have iptables-1.4.3.2 work with Linux-2.6.35.9 on our MIPS based platform. The command issued is
iptables -t mangle -A POSTROUTING -p udp -j <TC name> --map tos
iptables exits with input/output error (The same command was working on Linux-2.6.28.8). Then did a strace for the same on our target and seeing problem as below :
socket(PF_INET, SOCK_RAW, IPPROTO_RAW) = 3
getsockopt(3, SOL_IP, 0x40 /* IP_??? */, "mangle\0\0\0\0\0\34\200F\0\0\200\1\340 \244\200\1\340\244\200\7W\224\200\7W\f\0"..., [84]) = 0
getsockopt(3, SOL_IP, 0x41 /* IP_??? */, "mangle\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., [976]) = 0
setsockopt(3, SOL_IP, 0x40 /* IP_??? */, "mangle\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1240) = -1 EIO (Input/output error)
close(3) = 0
write(2, "iptables: "..., 10iptables: ) = 10
write(2, "Input/output error"..., 18Input/output error) = 18
write(2, ".\n"..., 2.
) = 2
munmap(0x2ab9b000, 75264) = 0
exit(1)
The above code is in libiptc.c ; Any suggestions to debug the error further would be helpful. Thanks.
EIO means that your custom "TC" target (or whatever it is you meant by it) module, i.e. xt_TC.c, does not adhere to the API. checkentry is not supposed to return values greater than zero (there is no meaning assigned to them) in 2.6.35 and up.
The issue seems to resolve by changing the following lines in linux-2.6.35/net/netfilter/x_tables.c
function xt_check_match:
changed following lines from :
if (par->match->checkentry != NULL) {
ret = par->match->checkentry(par);
if (ret < 0)
return ret;
else if (ret > 0)
{
/* Flag up potential errors. */
return -EIO;
}
}
to :
if (par->match->checkentry != NULL && !par->match->checkentry(par))
return -EINVAL;
Similarly in function xt_check_target : changed lines from:
if (par->target->checkentry != NULL) {
ret = par->target->checkentry(par);
if (ret < 0)
return ret;
else if (ret > 0)
{
/* Flag up potential errors. */
return -EIO;
}
}
to:
if (par->target->checkentry != NULL && !par->target->checkentry(par))
return -EINVAL;
These were the checks present in previous kernels. having the same checks solves the above issue. Thanks.
I have a simple verilog program that increments a 32 bit counter, converts the number to an ASCII string using $sformat and then pushes the string to the host machine 1 byte at a time using an FTDI FT245RL.
Unfortunately Xilinx XST keeps optimizing away the string register vector. I've tried mucking around with various initialization and access routines with no success. I can't seem to turn off optimization, and all of the examples I find online differ very little from my initialization routines. What am I doing wrong?
module counter(CK12, TXE_, WR, RD_, LED, USBD);
input CK12;
input TXE_;
output WR;
output RD_;
output [7:0] LED;
inout [7:0] USBD;
reg [31:0] count = 0;
reg [7:0] k;
reg wrf = 0;
reg rd = 1;
reg [7:0] lbyte = 8'b00000000;
reg td = 1;
parameter MEM_SIZE = 88;
parameter STR_SIZE = 11;
reg [MEM_SIZE - 1:0] str;
reg [7:0] strpos = 8'b00000000;
initial
begin
for (k = 0; k < MEM_SIZE; k = k + 1)
begin
str[k] = 0;
end
end
always #(posedge CK12)
begin
if (TXE_ == 0 && wrf == 1)
begin
count = count + 1;
wrf = 0;
end
else if (wrf == 0) // If we've already lowered the strobe, latch the data
begin
if(td)
begin
$sformat(str, "%0000000000d\n", count);
strpos = 0;
td = 0;
end
str = str << 8;
wrf = 1;
strpos = strpos + 1;
if(strpos == STR_SIZE)
td = 1;
end
end
assign RD_ = rd;
assign WR = wrf;
assign USBD = str[87:80];
assign LED = count[31:24];
endmodule
Loading device for application
Rf_Device from file '3s100e.nph' in
environment /opt/Xilinx/10.1/ISE.
WARNING:Xst:1293 - FF/Latch str_0
has a constant value of 0 in block
. This FF/Latch will be
trimmed during the optimization
process.
WARNING:Xst:1896 - Due to other
FF/Latch trimming, FF/Latch str_1
has a constant value of 0 in block
. This FF/Latch will be
trimmed during the optimization
process.
WARNING:Xst:1896 - Due to other
FF/Latch trimming, FF/Latch str_2
has a constant value of 0 in block
. This FF/Latch will be
trimmed during the optimization
process.
The $sformat task is unlikely to be synthesisable - consider what hardware the compiler would need to produce to implement this function! This means your 'str' register never gets updated, so the compiler thinks it can optimize it away. Consider a BCD counter, and maybe a lookup table to convert the BCD codes to ASCII codes.
AFAIK 'initial' blocks are not synthesisable. To initialize flops, use a reset signal. Memories need a 'for' loop like you have, but which triggers only after reset.