- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi~~
My SOPC setting have processor,PIO,SDRAM,FLASH..so on. I want to add a custom component which is a simple counter IP. (behavior: when I push the switch ,then the counter will plus one ) The following code is the counter IP. --- Quote Start --- output reg [ 7: 0] readdata; input clk; input [ 7: 0] in_port; reg [7:0] out; always @ ( clk or in_port) begin if ( in_port[7] == 0 ) readdata = 0; else if ( in_port[6] == 1 ) readdata = out + 8'b00000001; else readdata = out; out = readdata; end --- Quote End --- the IP setting is the following --- Quote Start --- counter count ( .readdata(readdata), // avalon_slave.readdata .clk (clk), // clock.clk .in_port (in_port) // conduit_end.export ); --- Quote End --- And the follwing code is C langauge in NIOS IDE --- Quote Start --- while(1){ count =IORD_ALTERA_AVALON_PIO_DATA(COUNTER_BASE); printf("count %d \n",count); } --- Quote End --- The above counter IP that I simulation with modelsim , and I can get the correct result. But when I download the .sof file to the DE0 board, I can't get the same result which simulation with modelsim. I use a lot of time to resolve this bug. Then I find the reg(the red color in first quote) that can't hole the last value. Therefore, I can't get the correct result. Normally when I declare the veriable type is reg, and this variable will keep the last value. But I run in NIOS, I don't have this feature. Counld you give me some suggestion Thank you very much. http://www.alteraforum.com/forum//proweb/misc/progress.gifLink Copied
6 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Replace always @ ( clk or in_port)
with always @ (posedge clk) You may also need to change further, if you want the counter to increment only once when you push the switch: now it keeps on increasing at the clk rate as long as you keep the switch pressed.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Replace always @ ( clk or in_port) with always @ (posedge clk) You may also need to change further, if you want the counter to increment only once when you push the switch: now it keeps on increasing at the clk rate as long as you keep the switch pressed. --- Quote End --- Thank you for your reply. Sorry, I try your suggestion,but it get the incorrect result. I don't know whether I misunderstanding your suggestion. I replace always @ ( clk or in_port) with always @ (posedge clk) In the normal case, when I press the switch, the counter will be increased once. However the experimental result shows the counter's number is a random number. The following is my experimental setting The initial the setting in_port = 8'b0000_0000 ,then the count shows number in NIOSII console with NIOS IDE --- Quote Start --- count is 0 --- Quote End --- next, I press the switch, I think the in_port = 8'b1000_0000 ,then the count shows number in NIOSII console with NIOS IDE --- Quote Start --- count is 208 (I want the count is 0) --- Quote End --- next, I keep on the switch pressed, the in_port = 8'b1000_0000 ,then the count shows number in NIOSII console with NIOS IDE --- Quote Start --- count is 30 (I want the count is 0) --- Quote End --- next, I keep on the switch pressed, the in_port = 8'b1000_0000 ,then the count shows number in NIOSII console with NIOS IDE --- Quote Start --- count is 93 (I want the count is 0) --- Quote End --- next, I press another switch, the in_port = 8'b1000_0010 ,then the count shows number in NIOSII console with NIOS IDE --- Quote Start --- count is 93 (I want the count is 1) --- Quote End --- next, I keep on switch pressed , the in_port = 8'b1000_0010 ,then the count shows number in NIOSII console with NIOS IDE --- Quote Start --- count is 93 (I want the count is 1) --- Quote End --- next, I release the switch, the in_port = 8'b1000_0000 (It will start to get the random number) ,then the count shows number in NIOSII console with NIOS IDE --- Quote Start --- count is 43 (I want the count is 1) --- Quote End --- next, I keep on the original switch pressed, the in_port = 8'b1000_0000 ,then the count shows number in NIOSII console with NIOS IDE --- Quote Start --- count is 58 (I want the count is 1) --- Quote End --- next, I press another switch, the in_port = 8'b1000_0010 ,then the count shows number in NIOSII console with NIOS IDE --- Quote Start --- count is 58 (I want the count is 2) --- Quote End --- Therefore I am almost crazy. I don't know why I can get this result. I replace always @ ( clk or in_port) with always @ (in_port) Let the command is executed in "always block" when the in_port changed. But the result is the same totally.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think there are a couple of flaws in your code
Issue# 1: As I said before, your code increments the counter on each clock pos edge whenever bit6 of input port is asserted. Now, what's clk frequency? If this is in the kHz or MHz range you will indeed get random numbers from the counter: I don't think you could keep the switch pressed for a single clock period! You'd rather get thousands of counts for every push, even if you are very very fast. Issue# 2: IMHO, using out and readdata registers in that way is not good. Replace = with <= for register assignments: e.g. out <= readdata; See http://en.wikipedia.org/wiki/verilog for explanation of difference. I guess in this 2 registers case, the = assignment is logically and syntactically correct but is not exactly synthesizable: that's why the simulation works but the real system doesn't. Apart this, I'd simply remove the 'out' register; readdata is enough. Example: (last is used to keep trace of previous pushbutton status and trigger the count only once) output reg [ 7: 0] readdata; input clk; input [ 7: 0] in_port; reg last; always @ ( posedge clk ) begin if ( in_port[7] == 0 ) readdata <= 8'b0; else if ( in_port[6] and ~last) // count only if switch has been pushed right now readdata <= readdata + 8'b1; // no need for else statement; everything is unchanged last <= in_port[6]; end- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- I think there are a couple of flaws in your code Issue# 1: As I said before, your code increments the counter on each clock pos edge whenever bit6 of input port is asserted. Now, what's clk frequency? If this is in the kHz or MHz range you will indeed get random numbers from the counter: I don't think you could keep the switch pressed for a single clock period! You'd rather get thousands of counts for every push, even if you are very very fast. Issue# 2: IMHO, using out and readdata registers in that way is not good. Replace = with <= for register assignments: e.g. out <= readdata; See http://en.wikipedia.org/wiki/verilog for explanation of difference. I guess in this 2 registers case, the = assignment is logically and syntactically correct but is not exactly synthesizable: that's why the simulation works but the real system doesn't. Apart this, I'd simply remove the 'out' register; readdata is enough. Example: (last is used to keep trace of previous pushbutton status and trigger the count only once) output reg [ 7: 0] readdata; input clk; input [ 7: 0] in_port; reg last; always @ ( posedge clk ) begin if ( in_port[7] == 0 ) readdata <= 8'b0; else if ( in_port[6] and ~last) // count only if switch has been pushed right now readdata <= readdata + 8'b1; // no need for else statement; everything is unchanged last <= in_port[6]; end --- Quote End --- Thank you for your help very much. It work successfully. Excuse me. May I ask another question? It is not related with the above problem. The following is the problem description. Now, I have a DE0 board, uClinux kernel, NIOSII processor, and u-boot. The version of uClinux kernel is uClinux-dist-20110603. The NIOS II version is 10.1 and quartus II version is 10.1. The u-boot version is u-boot-2011.06. I want to download the .sof file to DE0 board and then boot kernel. I have the three way to achieve the goal. I fail in one of them which is used the "bootm" command. First, I don't use the u-boot to boot kernel. Directly download the kernel to the memory and then boot kernel. (I use the compressed image kernel which is not .gz file but through "misc.c" ) Second, I use the u-boot's "go"command to boot kernel. Directly download the kernel to flash by using "flash programmer tool" of NIOS IDE. And then I copy the image kernel from flash through "cp.b" command. Finally, I key in "go" command booting kernel.(I use the uncompressed image kernel which is not through "misc.c") --- Quote Start --- ==>cp.b 02400000 01800000 400000 ==>go 01800000 --- Quote End --- Third, I use the u-boot's "bootm" command to boot kernel. It failed . (I use the compressed image kernel which is not .gz file but through "misc.c") 1. I create the uImage through the "mkimage" tool. The following is the settings --- Quote Start --- mkimage -n 'linux- 2.6' -A nios2 -O linux -T kernel -C none -a 0x01800000 -e 0x01800040 -d zImage uImage --- Quote End --- The following is board information --- Quote Start --- ==> bdinfo mem start = 0x01800000 mem size = 0x00800000 flash start = 0x82400000 flash size = 0x00400000 flash offset= 0x00000019 ethaddr = (not set) ip_addr = 0.0.0.0 baudrate = 1 bps --- Quote End --- 2. bootm command --- Quote Start --- ==>cp.b 02400000 01800000 400000 ==>bootm 01800000 - # # Booting kernel from Legacy Image at 01800000 ... Image Name: linux- 2.6 Image Type: NIOS II Linux Kernel Image (uncompressed) Data Size: 1457595 Bytes = 1.4 MiB Load Address: 01800000 Entry Point: 01800040 Verifying Checksum ... OK XIP Kernel Image ... OK <-----------------------------(stuck here.......) --- Quote End --- Could you give me some suggestion. Thank you very much. ps.I know the another address setting which will move the kernel in bootm command. I also try it, but still fail.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm afraid I neither have a DE0 board nor I ever used Linux kernel, then I can't help you on this point.
You'd better start a specific thread in the Linux or in the Development Kit section of the forum. But before this, I recommend you search the forum an answer: this could be a common issue.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That's fine.
Thank you for your reply.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page