Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
16 years ago

How to make sure nios send a single cycle control signal to peripheral?

hye everyone..this is a very basic question

i was testing how to control custom HW using nios. The custom HW in my case is just a simple counter.

ive attach my counter to avalon bus and manage to give signal and read output from it. however a single control signal from nios triggered a few counts on my counter.

e.g :

if i do this in c


printf("count=%d",IORD_8DIRECT(COUNTER_0_BASE,1));
IOWR_8DIRECT(COUNTER_0_BASE,0,1);
printf("count=%d",IORD_8DIRECT(COUNTER_0_BASE,1));
the output is:

0
3
but i actually want it to count up a single value each time the nios tell it to.

this is my current interface for counter<->avalonbus:

module avalon_counter(
    //avalon signal
    clk,
    reset_n,
    read,
    write,
    readdata,
    writedata,
    address,
    chipselect,
    
    //conduit
    outCNT
);
input    clk,
        read,
        write,
        chipselect,
        reset_n;
        
input    address;
                
input        writedata;
output    reg        readdata;
//component signal
reg        cnt_up;
reg        cnt_dwn;
wire        oCNT;
//conduit signal
output        outCNT;
assign    outCNT = oCNT;
always@(posedge clk)
begin
    if(!reset_n)
        readdata <= 8'b0;
    else
    begin
        if (chipselect == 1'b1)
        begin
            case(address)
            1'b0: 
            begin
                if(writedata)
                begin
                    cnt_up<=1'b1;
                    cnt_dwn<=1'b0;
                end
                else
                begin
                    cnt_up<=1'b0;
                    cnt_dwn<=1'b1;
                end
            end
            1'b1:
                readdata<={2'b00,oCNT};
            endcase
        end
        else
        begin
            cnt_up <= 1'b0;
            cnt_dwn<= 1'b0;
        end    
    end
end
counter    u1(
    .clk(clk),
    .resetn(reset_n),
    .cnt_up(cnt_up),
    .cnt_dwn(cnt_dwn),
    .oCNT(oCNT)
);
endmodule
i suspect that avalon only deassert chipselect after few cycle.so as long as the chipselect==1 cnt_up or cnt_dwn is always assert with value=1.

How can i make sure that a single command from nios only trigger a single count on my counter?

3 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    First, you are not testing if the CPU is reading or writing your component. While this doesn't have any impact in your case as you are using two different addresses it is best to only perform a write operation when the CPU actually intends to write. Usually when I design an avalon slave, I prefer to use the read and write control signals instead of chipselect and write_n.

    Second, in some cases, when accessing a 8-bit bus, the NIOS CPU performs 4 accesses to get a 32-bit value. I don't remember in which cases it does it, but now I don't bother anymore and always use 32-bit data busses even if I just have 8-bit values to exchange.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I notice that read/write operation does not use a single clk cycle from the output and ive also read it in avalon bus specification. but im still quite confuse how with a IOWR operation i can make sure that only a single pulse of CNT_UP signal will be catch by my customHW(counter). should i like check an edge of the signal from avalon bus inside my avalon_counter interface?

    --- Quote Start ---

    Second, in some cases, when accessing a 8-bit bus, the NIOS CPU performs 4 accesses to get a 32-bit value. I don't remember in which cases it does it, but now I don't bother anymore and always use 32-bit data busses even if I just have 8-bit values to exchange.

    --- Quote End ---

    but isnt IORD_8DIRECT macro specificly means we accessing 8bit. or it still access 32 bit but masked the 8bit LSB?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You specify yourself the number of wait cycles when you create the component in SOPC builder. With the default values, a read signal is active during two cycles and a write signal during one cycle, so your code should be fine and you don't need to detect an edge on the avalon control signals.

    For your second question, I don't know. I stopped trying to understand how the CPU does the 8-bit accesses and just do everything with 32-bit data busses. It saves a lot of trouble ;)

    I think that the CPU is trying to do an 8-bit access but the switching fabric divides it in 4 8-bit accesses, but I'm not sure.